예제 #1
0
        UiLoadedObject ParseObjectInternal(
            Type objType,
            XElement el,
            List <XmlObjectMap> objectMaps,
            Dictionary <string, InterfaceColor> interfaceColors,
            Dictionary <string, InterfaceModel> interfaceModels,
            Dictionary <string, InterfaceImage> interfaceImages
            )
        {
            UiXmlReflection.GetProperties(
                objType,
                out Dictionary <string, PropertyInfo> elements,
                out Dictionary <string, PropertyInfo> attributes,
                out PropertyInfo contentProperty,
                out PropertyInfo reinitProperty
                );
            var result = new UiLoadedObject(objType);
            List <UiLoadedObject> contentObjects = null;
            bool isContentList = false;

            if (contentProperty != null)
            {
                isContentList = Activator.CreateInstance(contentProperty.PropertyType) is IList;
                if (isContentList)
                {
                    contentObjects = new List <UiLoadedObject>();
                }
            }

            if (reinitProperty != null)
            {
                result.Setters.Add(new UiSimpleProperty(reinitProperty, new UiRecreateHandle(result)));
            }
            if (objectMaps != null)
            {
                var li = (IXmlLineInfo)el;
                objectMaps.Add(new XmlObjectMap()
                {
                    Line    = li.LineNumber,
                    Column  = li.LinePosition,
                    Element = el,
                    Object  = result
                });
            }
            foreach (var attr in el.Attributes())
            {
                var          pname = attr.Name.ToString();
                PropertyInfo property;
                if (attributes.TryGetValue(pname, out property))
                {
                    object value = null;
                    var    ptype = property.PropertyType;
                    if (ptype.IsEnum)
                    {
                        value = Enum.Parse(ptype, attr.Value, true);
                    }
                    else if (ptype == typeof(InterfaceColor))
                    {
                        InterfaceColor color;
                        if (!interfaceColors.TryGetValue(attr.Value, out color))
                        {
                            color = new InterfaceColor()
                            {
                                Color = Parser.Color(attr.Value)
                            };
                        }
                        value = color;
                    }
                    else if (ptype == typeof(InterfaceModel) && interfaceModels.TryGetValue(attr.Value, out var model))
                    {
                        value = model;
                    }
                    else if (ptype == typeof(InterfaceImage) && interfaceImages.TryGetValue(attr.Value, out var image))
                    {
                        value = image;
                    }
                    else if (ptype == typeof(string))
                    {
                        value = attr.Value;
                    }
                    else
                    {
                        value = Convert.ChangeType(attr.Value, ptype, CultureInfo.InvariantCulture);
                    }
                    result.Setters.Add(new UiSimpleProperty(property, value));
                }
                else
                {
                    //Throw error?
                }
            }
            foreach (var child in el.Elements())
            {
                var          childName = child.Name.ToString();
                PropertyInfo property  = null;
                if (childName.Contains("."))
                {
                    childName = childName.Split('.')[1];
                    if (!elements.TryGetValue(childName, out property))
                    {
                        throw new Exception($"{el.Name} does not have property {childName}");
                    }
                }
                if (property != null)
                {
                    var v = Activator.CreateInstance(property.PropertyType);
                    if (v is IList list)
                    {
                        var listType = property.PropertyType.GenericTypeArguments[0];
                        if (PrimitiveList(property, child, listType, out var primlist))
                        {
                            result.Setters.Add(primlist);
                        }
                        else
                        {
                            var objs = new List <UiLoadedObject>();
                            foreach (var itemXml in child.Elements())
                            {
                                var nt = UiXmlReflection.Instantiate(itemXml.Name.ToString()).GetType();
                                objs.Add(ParseObjectInternal(nt, itemXml, objectMaps, interfaceColors, interfaceModels, interfaceImages));
                            }

                            result.Setters.Add(new UiComplexList(property, objs.ToArray()));
                        }
                    }
                    else if (v is IDictionary dict)
                    {
                        var keyType   = property.PropertyType.GenericTypeArguments[0];
                        var valueType = property.PropertyType.GenericTypeArguments[1];
                        if (PrimitiveDictionary(child, property, keyType, valueType, out var primdict))
                        {
                            result.Setters.Add(primdict);
                        }
                        else
                        {
                            var keys   = new List <object>();
                            var values = new List <UiLoadedObject>();
                            foreach (var itemXml in child.Elements())
                            {
                                var nt = UiXmlReflection.Instantiate(itemXml.Name.ToString()).GetType();
                                values.Add(ParseObjectInternal(nt, itemXml, objectMaps, interfaceColors, interfaceModels, interfaceImages));
                                keys.Add(GetDictionaryKey(itemXml, keyType));
                            }
                            result.Setters.Add(new UiComplexDictionary(property, keys.ToArray(), values.ToArray()));
                        }
                    }
                    else if (property.SetMethod != null)
                    {
                        var obj = ParseObjectInternal(property.PropertyType, child, objectMaps, interfaceColors,
                                                      interfaceModels, interfaceImages);
                        result.Setters.Add(new UiComplexProperty(property, obj));
                    }
                }
                else
                {
                    if (contentProperty == null)
                    {
                        throw new Exception($"{objType.FullName} lacks UiContentAttribute property");
                    }
                    var nt      = UiXmlReflection.Instantiate(child.Name.ToString()).GetType();
                    var content = ParseObjectInternal(nt, child, objectMaps, interfaceColors, interfaceModels,
                                                      interfaceImages);
                    if (isContentList)
                    {
                        contentObjects.Add(content);
                    }
                    else
                    {
                        result.Setters.Add(new UiComplexProperty(contentProperty, content));
                    }
                }
                if (objectMaps != null)
                {
                    var nEnd = child.NodesAfterSelf().FirstOrDefault();
                    var li   = (IXmlLineInfo)nEnd;
                    objectMaps.Add(new XmlObjectMap()
                    {
                        Line   = li.LineNumber,
                        Column = li.LinePosition,
                        Object = result
                    });
                }
            }
            if (isContentList)
            {
                result.Setters.Add(new UiComplexList(contentProperty, contentObjects.ToArray()));
            }
            return(result);
        }
예제 #2
0
 public UiComplexProperty(PropertyInfo p, UiLoadedObject v) : base(p)
 {
     Value = v;
 }
예제 #3
0
 internal UiRecreateHandle(UiLoadedObject loaded)
 {
     this.loaded = loaded;
 }