#region ================== Copyright (c) 2007 Pascal vd Heiden /* * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com * This program is released under GNU General Public License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #endregion #region ================== Namespaces using System; using System.Collections.Generic; using System.IO; #endregion namespace CodeImp.DoomBuilder.ZDoom { public sealed class TexturesParser : ZDTextParser { #region ================== Delegates #endregion #region ================== Constants #endregion #region ================== Variables private Dictionary textures; private Dictionary flats; private Dictionary sprites; #endregion #region ================== Properties public ICollection Textures { get { return textures.Values; } } public ICollection Flats { get { return flats.Values; } } public ICollection Sprites { get { return sprites.Values; } } #endregion #region ================== Constructor / Disposer // Constructor public TexturesParser() { // Syntax whitespace = "\n \t\r\u00A0"; //mxd. non-breaking space is also space :) specialtokens = ",{}\n"; // Initialize textures = new Dictionary(StringComparer.Ordinal); flats = new Dictionary(StringComparer.Ordinal); sprites = new Dictionary(StringComparer.Ordinal); } #endregion #region ================== Parsing // This parses the given stream // Returns false on errors public override bool Parse(Stream stream, string sourcefilename) { base.Parse(stream, sourcefilename); // Continue until at the end of the stream while(SkipWhitespace(true)) { // Read a token string objdeclaration = ReadToken(); if(objdeclaration != null) { objdeclaration = objdeclaration.ToLowerInvariant(); if(objdeclaration == "texture") { // Read texture structure TextureStructure tx = new TextureStructure(this, "texture"); if(this.HasError) break; // if a limit for the texture name length is set make sure that it's not exceeded if((General.Map.Config.MaxTextureNameLength > 0) && (tx.Name.Length > General.Map.Config.MaxTextureNameLength)) { General.ErrorLogger.Add(ErrorType.Error, "Texture name \"" + tx.Name + "\" too long. Texture names must have a length of " + General.Map.Config.MaxTextureNameLength + " characters or less"); } else { // Add the texture textures[tx.Name] = tx; if(!General.Map.Config.MixTexturesFlats) flats[tx.Name] = tx; //mxd. If MixTexturesFlats is set, textures and flats will be mixed in DataManager anyway } } else if(objdeclaration == "sprite") { // Read sprite structure TextureStructure tx = new TextureStructure(this, "sprite"); if(this.HasError) break; // if a limit for the sprite name length is set make sure that it's not exceeded if((General.Map.Config.MaxTextureNameLength > 0) && (tx.Name.Length > General.Map.Config.MaxTextureNameLength)) { General.ErrorLogger.Add(ErrorType.Error, "Sprite name \"" + tx.Name + "\" too long. Sprite names must have a length of " + General.Map.Config.MaxTextureNameLength + " characters or less"); } else { // Add the sprite sprites[tx.Name] = tx; } } else if(objdeclaration == "walltexture") { // Read walltexture structure TextureStructure tx = new TextureStructure(this, "walltexture"); if(this.HasError) break; // if a limit for the walltexture name length is set make sure that it's not exceeded if((General.Map.Config.MaxTextureNameLength > 0) && (tx.Name.Length > General.Map.Config.MaxTextureNameLength)) { General.ErrorLogger.Add(ErrorType.Error, "WallTexture name \"" + tx.Name + "\" too long. WallTexture names must have a length of " + General.Map.Config.MaxTextureNameLength + " characters or less"); } else { // Add the walltexture if(!textures.ContainsKey(tx.Name) || (textures[tx.Name].TypeName != "texture")) textures[tx.Name] = tx; } } else if(objdeclaration == "flat") { // Read flat structure TextureStructure tx = new TextureStructure(this, "flat"); if(this.HasError) break; // if a limit for the flat name length is set make sure that it's not exceeded if((General.Map.Config.MaxTextureNameLength > 0) && (tx.Name.Length > General.Map.Config.MaxTextureNameLength)) { General.ErrorLogger.Add(ErrorType.Error, "Flat name \"" + tx.Name + "\" too long. Flat names must have a length of " + General.Map.Config.MaxTextureNameLength + " characters or less"); } else { // Add the flat if(!flats.ContainsKey(tx.Name) || (flats[tx.Name].TypeName != "texture")) flats[tx.Name] = tx; } } else { // Unknown structure! // Best we can do now is just find the first { and then // follow the scopes until the matching } is found string token2; do { if(!SkipWhitespace(true)) break; token2 = ReadToken(); if(token2 == null) break; } while(token2 != "{"); int scopelevel = 1; do { if(!SkipWhitespace(true)) break; token2 = ReadToken(); if(token2 == null) break; if(token2 == "{") scopelevel++; if(token2 == "}") scopelevel--; } while(scopelevel > 0); } } } // Return true when no errors occurred return (ErrorDescription == null); } #endregion } }