コード例 #1
0
 public StatSubtypeDefinition(StatTypeDefinition type, string name)
 {
     Type       = type;
     Name       = name;
     Fields     = new Dictionary <string, StatField>();
     SubObjects = new Dictionary <string, StatSubtypeDefinition>();
 }
コード例 #2
0
        private StatSubtypeDefinition FindSubtype(StatTypeDefinition type, string declarationName, StatDeclaration declaration)
        {
            if (type.SubtypeProperty == null)
            {
                return(type.Subtypes.Values.First());
            }

            if (declaration.Properties.TryGetValue(type.SubtypeProperty, out object subtypeName))
            {
                var name = (string)subtypeName;
                if (type.Subtypes.TryGetValue(name, out StatSubtypeDefinition subtype))
                {
                    return(subtype);
                }
                else
                {
                    Context.LogError(DiagnosticCode.StatSubtypeMissing, $"Stat declaration '{declarationName}' references unknown subtype '{name}'",
                                     declaration.Location.FileName, declaration.Location.StartLine);
                    return(null);
                }
            }
            else
            {
                Context.LogError(DiagnosticCode.StatSubtypeMissing, $"Stat declaration '{declarationName}' is missing subtype property '{type.SubtypeProperty}'",
                                 declaration.Location.FileName, declaration.Location.StartLine);
                return(null);
            }
        }
コード例 #3
0
        public Dictionary <string, StatDeclaration> ResolveBaseClasses(StatTypeDefinition definition, Dictionary <string, StatDeclaration> declarations)
        {
            var mappings = new List <BaseClassMapping>();
            var resolved = new Dictionary <string, StatDeclaration>();

            foreach (var declaration in declarations)
            {
                var succeeded = ResolveBaseClass(definition, declaration.Value, declarations, out StatDeclaration baseClass);
                if (succeeded && baseClass != null)
                {
                    mappings.Add(new BaseClassMapping
                    {
                        Declaration = declaration.Value,
                        BaseClass   = baseClass
                    });
                }

                if (succeeded || AllowMappingErrors)
                {
                    resolved.Add(declaration.Key, declaration.Value);
                }
            }

            PropagateInheritedProperties(mappings);

            return(resolved);
        }
コード例 #4
0
        public bool ResolveBaseClass(
            StatTypeDefinition definition, StatDeclaration declaration,
            Dictionary <string, StatDeclaration> declarations,
            out StatDeclaration baseClassDeclaration)
        {
            var props = declaration.Properties;
            var name  = (string)props[definition.NameProperty];

            if (definition.BaseClassProperty != null && props.ContainsKey(definition.BaseClassProperty))
            {
                var baseClass = (string)props[definition.BaseClassProperty];

                if (declarations.TryGetValue(baseClass, out StatDeclaration baseDeclaration))
                {
                    baseClassDeclaration = baseDeclaration;
                    return(true);
                }
                else
                {
                    Context.LogError(DiagnosticCode.StatBaseClassNotKnown, $"Stat declaration '{name}' references nonexistent base class '{baseClass}'",
                                     declaration.Location.FileName, declaration.Location.StartLine, name);
                    baseClassDeclaration = null;
                    return(false);
                }
            }

            baseClassDeclaration = null;
            return(true);
        }
コード例 #5
0
        private void AddSubtype(StatTypeDefinition definition, string subtypeName, IEnumerable <XElement> fields)
        {
            var subtype = new StatSubtypeDefinition(definition, subtypeName);

            foreach (var field in fields)
            {
                AddField(definition, subtype, field);
            }

            definition.Subtypes.Add(subtypeName, subtype);
        }
コード例 #6
0
        private void AddDefinition(XElement defn)
        {
            var name       = defn.Attribute("name").Value;
            var parentName = defn.Attribute("export_type")?.Value ?? name;

            if (!Definitions.TryGetValue(parentName, out StatTypeDefinition definition))
            {
                var subtypeProperty = defn.Attribute("subtype_property")?.Value ?? null;
                definition = new StatTypeDefinition(parentName, subtypeProperty);
                Definitions.Add(parentName, definition);
            }

            var fields = defn.Element("field_definitions").Elements("field_definition");

            AddSubtype(definition, name, fields);
        }
コード例 #7
0
        private void AddField(StatTypeDefinition definition, StatSubtypeDefinition subtype, XElement field)
        {
            if (field.Attribute("export_name").Value == "")
            {
                return;
            }

            var             fieldName   = field.Attribute("export_name").Value;
            var             typeName    = field.Attribute("type").Value;
            StatEnumeration enumeration = null;
            List <StatReferenceConstraint> referenceConstraints = null;

            switch (typeName)
            {
            case "Enumeration":
            case "EnumerationList":
                var enumName = field.Attribute("enumeration_type_name").Value;
                enumeration = Enumerations[enumName];
                break;

            case "Name":
                if (definition.NameProperty == null)
                {
                    definition.NameProperty = fieldName;
                }
                else if (definition.NameProperty != fieldName)
                {
                    throw new Exception($"Conflicting Name property for type '{definition.Name}': First seen using '{definition.NameProperty}', now seen using '{fieldName}'.");
                }
                break;

            case "BaseClass":
                if (definition.BaseClassProperty == null)
                {
                    definition.BaseClassProperty = fieldName;
                }
                else if (definition.BaseClassProperty != fieldName)
                {
                    throw new Exception($"Conflicting BaseClass for type '{definition.Name}': First seen using '{definition.BaseClassProperty}', now seen using '{fieldName}'.");
                }
                break;

            case "StatReference":
            case "StatReferences":
                referenceConstraints = new List <StatReferenceConstraint>();
                var descriptions = field.Element("stat_descriptions");
                if (descriptions == null)
                {
                    throw new Exception("Field of type 'StatReference' must have a list of stat types in the <stat_descriptions> node");
                }

                var descs = descriptions.Elements("description");
                foreach (var desc in descs)
                {
                    var constraint = new StatReferenceConstraint
                    {
                        StatType    = desc.Attribute("stat_type").Value,
                        StatSubtype = desc.Attribute("stat_subtype")?.Value ?? null
                    };
                    referenceConstraints.Add(constraint);
                }

                break;

            case "Boolean":
            case "Integer":
            case "Float":
            case "String":
            case "TranslatedString":
            case "RootTemplate":
            case "Comment":
            case "Color":
            case "Requirements":
            case "Properties":
            case "Conditions":
            case "Passthrough":
            case "UUID":
                break;

            default:
                throw new Exception($"Unsupported stat field type: '{typeName}'");
            }

            var statField = new StatField
            {
                Name           = fieldName,
                Type           = typeName,
                EnumType       = enumeration,
                ReferenceTypes = referenceConstraints
            };

            subtype.Fields.Add(fieldName, statField);

            if (typeName == "TranslatedString")
            {
                var translatedKeyRefField = new StatField
                {
                    Name     = fieldName + "Ref",
                    Type     = typeName,
                    EnumType = enumeration
                };
                subtype.Fields.Add(fieldName + "Ref", translatedKeyRefField);
            }
        }