/** 递归查找自定义组件下的自定义组件 */
        private static void FillInfoRecursively(IExportable exportComponentInfo, Dictionary <string, ExportComponentInfo> exportInfoMap, Dictionary <string, ExportCustomElementInfo> exportCustomElementInfoMap, FairyGUI.UIPackage pak, List <FairyGUI.PackageItem> allComponents)
        {
            //递归查找component下面元素
            var rootItem     = exportComponentInfo.PakItem;
            var loadedPi     = rootItem.Load();
            var piInst       = UIPackage.CreateObject(pak.name, rootItem.name) as FairyGUI.GComponent;
            var displayItems = piInst.GetChildren();// .displayList;

            for (int i = 0, c = displayItems.Length; i < c; i++)
            {
                var displayItem = displayItems[i];
                var item        = displayItem.packageItem;


                //var xml = item.componentData;
                //var xml = displayItem.desc;
                //字段名
                var fieldName = displayItem.name; // xml.GetAttribute("name");
                //字段id
                var id = displayItem.id;          //xml.GetAttribute("id");
                //是否应用了包内的组建
                //bool hasSrc =  xml.HasAttribute("src");

                //是否是否引用了其他包
                bool   isRefPakComponent = false; // xml.HasAttribute("pkg");
                string refPakId          = "";    // xml.GetAttribute("pkg") : "";
                string refPakName        = "";
                if (isRefPakComponent)
                {
                    //LogA("1.1$$ xml.node.src: " + xml.GetAttribute("src"));
                }
                //LogA("2$$ desc xml.node.name: " + xml.name + "  fieldName:" + fieldName);

                //ultra feature
                string CustomData = string.Concat(displayItem.data);// xml.GetAttribute("customData");
                //Debug.Log("$$ " + fieldName + " customData:" + CustomData);
                // 否则displayListItem为内置控件
                if (item == null) // == null
                {
                    //内置控件类型或者自定义控件元素名称 组件内的内置控件
                    var builtInTypeName = displayItem.GetType().Name.ToLower().Remove(0, 1);//xml.name;
                    if (builtInElementType.ContainsKey(builtInTypeName))
                    {
                        LogA("2.1$$ find exist builtInElementType: " + builtInTypeName);
                        var exportInfo = new ExportInfo();
                        exportInfo.ExportCategory  = ExportInfo.EExportCategory.builtInElement;
                        exportInfo.DisplayListItem = item;
                        exportInfo.ExportName      = fieldName;
                        exportInfo.ExportType      = builtInElementType[builtInTypeName];
                        exportInfo.ExportTypeName  = exportInfo.ExportType.FullName;
                        exportInfo.NodeIndex       = i;
                        exportInfo.ID         = id;
                        exportInfo.CustomData = CustomData;
                        exportComponentInfo.ExportInfos.Add(exportInfo);
                    }
                    else
                    {
                        Debug.LogError("2.1$$ find unexpected builtInElementType: " + builtInTypeName + " fieldName:" + fieldName);
                    }

                    //LogA("2.1$$ pakItem is null desc xml.node.name:" + xml.name + " fieldName:" + fieldName);
                }
                else //item不为null 引用的是包内资源或组件
                {
                    //if (allComponents.Contains(item))
                    //{
                    //    LogA("2.2$$ exist in allComponents name: " + item.name);
                    //}
                    //else
                    //{
                    //    LogA("2.2$$ not exist in allComponents name: " + item.name);
                    //}

                    item.Load();

                    isRefPakComponent = item.owner.id != rootItem.owner.id;
                    refPakId          = isRefPakComponent ? item.owner.id : "";
                    refPakName        = isRefPakComponent ? UIPackage.GetById(refPakId).name : "";

                    //资源和自定义动画
                    if (item.type == FairyGUI.PackageItemType.Image)
                    {
                        LogA("4$$ find elementType: Image");
                        var elementType = new ExportInfo();
                        elementType.ExportCategory  = ExportInfo.EExportCategory.resElement;
                        elementType.ExportName      = fieldName; //item.name;
                        elementType.ExportType      = typeof(FairyGUI.GImage);
                        elementType.ExportTypeName  = elementType.ExportType.FullName;
                        elementType.NodeIndex       = i;
                        elementType.DisplayListItem = item;
                        elementType.ID         = id;
                        elementType.CustomData = CustomData;
                        exportComponentInfo.ExportInfos.Add(elementType);
                    }
                    else if (item.type == FairyGUI.PackageItemType.MovieClip)
                    {
                        LogA("4$$ find elementType: MovieClip");
                        var elementType = new ExportInfo();
                        elementType.ExportCategory  = ExportInfo.EExportCategory.resElement;
                        elementType.ExportName      = fieldName;// item.name;
                        elementType.ExportType      = typeof(FairyGUI.GMovieClip);
                        elementType.ExportTypeName  = elementType.ExportType.FullName;
                        elementType.NodeIndex       = i;
                        elementType.DisplayListItem = item;
                        elementType.ID         = id;
                        elementType.CustomData = CustomData;
                        exportComponentInfo.ExportInfos.Add(elementType);
                    }
                    else if (item.type == FairyGUI.PackageItemType.Sound)
                    {
                    }
                    else if (item.type == FairyGUI.PackageItemType.Atlas)
                    {
                    }
                    else if (item.type == FairyGUI.PackageItemType.Font)
                    {
                    }
                    else if (item.type == FairyGUI.PackageItemType.Misc)
                    {
                    }
                    // custom elements 自定义控件元素
                    else if (item.type == FairyGUI.PackageItemType.Component)
                    {
                        string extention = item.objectType.ToString();//.componentData.GetAttribute("extention");
                        if (extention != "Component")
                        {
                            var TypeName = item.name;
                            Debug.Log("$$ fetch type:" + TypeName);
                            // 引用了包内自定义控件
                            if (customComponentType.ContainsKey(extention))
                            {
                                // 导出自定义控件类型
                                if (!exportCustomElementInfoMap.ContainsKey(TypeName) && !isRefPakComponent)
                                {
                                    var packageName             = pak.name;
                                    var exportCustomElementInfo = new ExportCustomElementInfo();
                                    exportCustomElementInfo.ExportExtentionType = customComponentType[extention];
                                    exportCustomElementInfo.ExportPackageName   = string.Join(".", new string[] {
                                        CodeGeneratorSetting.RootNameSpace,
                                        packageName,
                                    });
                                    exportCustomElementInfo.ExportTypeName = TypeName;
                                    exportCustomElementInfo.pakItem        = item;
                                    exportCustomElementInfo.ID             = item.id;
                                    exportCustomElementInfoMap[TypeName]   = exportCustomElementInfo;
                                    //exportComponentInfo.pakItem = item;
                                    //exportComponentInfo.ID = item.id;
                                    FillInfoRecursively(exportCustomElementInfo, exportInfoMap, exportCustomElementInfoMap, pak, allComponents);
                                }
                                LogA("6$$ find elementType:" + extention);

                                //为组件添加字段 组件里面添加自定义控件
                                var elementType = new ExportInfo();
                                elementType.ExportCategory = ExportInfo.EExportCategory.customElement;
                                elementType.ExportName     = fieldName;
                                elementType.ExportType     = customComponentType[extention];
                                elementType.isTypeInPak    = !isRefPakComponent;
                                string FullName = string.Join(".", new string[] { CodeGeneratorSetting.RootNameSpace, refPakName, TypeName });
                                if (isRefPakComponent)
                                {
                                    //跨包只使用基础类型
                                    FullName = customComponentType[extention].FullName;
                                }
                                elementType.ExportTypeName  = isRefPakComponent? FullName : string.Join(".", new string[] { CodeGeneratorSetting.RootNameSpace, pak.name, TypeName });
                                elementType.ExtentionType   = customComponentType[extention];
                                elementType.NodeIndex       = i;
                                elementType.DisplayListItem = item;
                                elementType.ID         = id;
                                elementType.CustomData = CustomData;
                                exportComponentInfo.ExportInfos.Add(elementType);
                            }
                            // 引用了包内自定义组件
                        }
                        else
                        {
                            var TypeName = item.name;
                            Debug.Log("$$ fetch type:" + TypeName);
                            // 添加新的导出信息
                            if (!exportInfoMap.ContainsKey(TypeName) && !isRefPakComponent)
                            {
                                LogA("8$$ find inline component:" + extention);
                                var componentType = new ExportComponentInfo();
                                var packageName   = pak.name;
                                componentType.ExportTypeName    = TypeName;
                                componentType.ExportPackageName = string.Join(".", new string[] {
                                    CodeGeneratorSetting.RootNameSpace,
                                    packageName,
                                    //componentType.ExportTypeName,
                                });
                                componentType.pakItem = item;
                                componentType.ID      = item.id;
                                exportInfoMap[componentType.ExportTypeName] = componentType;
                                //exportComponentInfo.ExportComponentInfos.Add(componentType);
                                FillInfoRecursively(componentType, exportInfoMap, exportCustomElementInfoMap, pak, allComponents);
                            }

                            // 为组件添加自定义组件成员或字段 组件里面有组件 内嵌
                            var componentTypeFiled = new ExportInfo();
                            componentTypeFiled.ExportCategory = ExportInfo.EExportCategory.customComponent;
                            componentTypeFiled.ExportName     = fieldName;
                            string FullName = string.Join(".", new string[] { CodeGeneratorSetting.RootNameSpace, refPakName, TypeName });
                            if (isRefPakComponent)
                            {
                                //跨包只使用基础类型
                                FullName = typeof(FairyGUI.GComponent).FullName;
                            }
                            componentTypeFiled.ExportTypeName  = isRefPakComponent? FullName: TypeName;
                            componentTypeFiled.DisplayListItem = item;
                            componentTypeFiled.isTypeInPak     = !isRefPakComponent;
                            componentTypeFiled.ExtentionType   = typeof(FairyGUI.GComponent);
                            componentTypeFiled.NodeIndex       = i;
                            componentTypeFiled.ID         = id;
                            componentTypeFiled.CustomData = CustomData;
                            exportComponentInfo.ExportInfos.Add(componentTypeFiled);
                        }
                    }
                }//end if(item != null)
            }
            piInst.Dispose();
        }
        public static ExportPipeInfo ParseExportInfo(List <FairyGUI.PackageItem> itemsToGen, FairyGUI.UIPackage pak)
        {
            //处理fairyGUI包根目录
            var allComponents = new List <FairyGUI.PackageItem>();

            pak.GetItems().ForEach((item) =>
            {
                if (item.type == FairyGUI.PackageItemType.Component)
                {
                    allComponents.Add(item);
                }
            });

            /** 需要导出的自定义组件信息*/
            var exportInfoMap = new Dictionary <string, ExportComponentInfo>();
            /** 需要导出的自定义元素信息 */
            var exportCustomElementInfoMap = new Dictionary <string, ExportCustomElementInfo>();

            itemsToGen.ForEach((item) =>
            {
                /** 处理组件 */
                if (item.type == FairyGUI.PackageItemType.Component)
                {
                    item.Load();

                    //var xml = item.componentData;
                    /** 自定控件继承的父类类型 */
                    string extention = item.objectType.ToString();//xml.GetAttribute("extention");

                    // elements
                    if (extention != "Component")
                    {
                        var TypeName = item.name;
                        // 引用了包内自定义控件
                        if (customComponentType.ContainsKey(extention))
                        {
                            // 导出自定义控件类型
                            if (!exportCustomElementInfoMap.ContainsKey(TypeName))
                            {
                                var packageName             = pak.name;
                                var exportCustomElementInfo = new ExportCustomElementInfo();
                                exportCustomElementInfo.ExportExtentionType = customComponentType[extention];
                                exportCustomElementInfo.ExportPackageName   = string.Join(".", new string[] {
                                    CodeGeneratorSetting.RootNameSpace,
                                    packageName,
                                });
                                exportCustomElementInfo.ExportTypeName = TypeName;
                                exportCustomElementInfo.pakItem        = item;
                                exportCustomElementInfo.ID             = item.id;
                                exportCustomElementInfoMap[TypeName]   = exportCustomElementInfo;
                                FillInfoRecursively(exportCustomElementInfo, exportInfoMap, exportCustomElementInfoMap, pak, allComponents);
                            }
                        }
                        // 引用了包内自定义组件
                    }
                    else //root component
                    {
                        var componentType               = new ExportComponentInfo();
                        var packageName                 = pak.name;
                        componentType.ExportTypeName    = item.name;
                        componentType.ExportPackageName = string.Join(".", new string[] {
                            CodeGeneratorSetting.RootNameSpace,
                            packageName,
                            //componentType.ExportTypeName,
                        });
                        componentType.pakItem = item;
                        componentType.ID      = item.id;
                        exportInfoMap[componentType.ExportTypeName] = componentType;

                        //递归查找component下面元素
                        FillInfoRecursively(componentType, exportInfoMap, exportCustomElementInfoMap, pak, allComponents);

                        /*
                         * foreach (var kv in exportInfoMap)
                         * {
                         *  LogB("1$$ customComponent type to export:" + kv.Key);
                         *
                         *  kv.Value.ExportInfos.ForEach((info) =>
                         *  {
                         *      LogB("1.1$$ export Category" + info.ExportCategory.ToString() + " name:" + info.ExportName + " type: " + info.ExportTypeName);
                         *  });
                         *
                         * }
                         *
                         * foreach (var kv in exportCustomElementInfoMap)
                         * {
                         *  LogB("2$$ customElement type to export:" + kv.Key);
                         * }
                         */
                    }
                }
            });

            ExportPipeInfo exportPipeInfo = new ExportPipeInfo()
            {
                ExportComponentInfoMap     = exportInfoMap,
                ExportCustomElementInfoMap = exportCustomElementInfoMap
            };

            return(exportPipeInfo);
        }