Example #1
0
 private void AddSchemaType(SchemaType type)
 {
     SchemaTypeMap[type.Name] = type;
     SchemaTypes.Add(type.Name);
 }
Example #2
0
        /// <summary>
        /// Loads a Noita schema file (data/schemas) as an XWitch schema object.
        /// </summary>
        /// <param name="reader">Stream reader.</param>
        /// <param name="id">Optional ID to use for this schema (`"noita"` by default).</param>
        /// <param name="metaschema">Optional XWitch schema object that defines unknown types used in the schema (will try to get an already registered schema with the ID `ecs` if this isn't passed).</param>
        public void LoadFromNoitaSchema(StreamReader reader, string id = null, Schema metaschema = null)
        {
            if (metaschema == null)
            {
                metaschema = Schema.TryGetSchema(DEFAULT_NOITA_METASCHEMA_ID);
                if (metaschema == null)
                {
                    throw new Exception($"No metaschema given to LoadNoitaSchema and no schema with the ID 'ecs' registered");
                }
            }

            if (id == null)
            {
                id = "noita";
            }
            ID = id;

            ResetData();
            var doc = new HtmlDocument();

            doc.Load(reader);

            if (doc.DocumentNode.ChildNodes.Count == 0)
            {
                return;
            }

            var root = doc.DocumentNode.ChildNodes[0];

            if (root.NodeType != HtmlNodeType.Element || root.Name != "Schema")
            {
                return;
            }

            if (TryGetSchema(ID) != null)
            {
                throw new Exception($"Schema with ID {ID} is already loaded");
            }

            AddToLibrary(this);

            for (var i = 0; i < root.ChildNodes.Count; i++)
            {
                var child = root.ChildNodes[i];
                if (child.NodeType != HtmlNodeType.Element)
                {
                    continue;
                }
                var type = new SchemaObjectType();

                type.ArrayType  = false;
                type.FieldNames = new List <string>();
                type.FieldTypes = new Dictionary <string, SchemaType>();
                type.Name       = child.GetAttributeValue("component_name", null);

                AddSchemaType(type);

                for (var j = 0; j < child.ChildNodes.Count; j++)
                {
                    var varchild = child.ChildNodes[j];
                    if (varchild.NodeType != HtmlNodeType.Element)
                    {
                        continue;
                    }

                    var name = varchild.GetAttributeValue("name", null);
                    var size = int.Parse(varchild.GetAttributeValue("size", null));

                    SchemaType field_type    = null;
                    var        override_type = metaschema.GetSchemaOverride(type.Name, name);

                    if (override_type == null)
                    {
                        var ceng_type_name = varchild.GetAttributeValue("type", null).Trim();
                        field_type = metaschema.GetSchemaType(ceng_type_name);

                        if (field_type.ExpectedSize != size)
                        {
                            throw new Exception($"Type size mismatch: metaschema-defined type '{field_type.Name}' expects size to be {field_type.ExpectedSize}, but actual size of field '{name}' in component '{type.Name}' is {size}");
                        }
                    }
                    else
                    {
                        field_type = override_type;
                    }

                    type.FieldNames.Add(name);
                    type.FieldTypes[name] = field_type;
                }
            }
        }