using System; using System.Collections.Generic; using System.Globalization; using System.IO; using UnityEngine; using Framework.Support; namespace Framework.Layers { /// Parses layer mask list files internal static class LayerMaskListParser { /// Reads a layer mask from the specified string reader /// Dictionary the parsed layer masks will be stored in /// Reader from which the layer masks will be read public static void Read(IDictionary dictionary, StringReader reader) { for(; ; ) { string line = reader.ReadLine(); if(line == null) { break; } parseLine(dictionary, line); } } /// Parses a single line from a layer mask list /// Dictionary that found layer masks will be stored in /// Line that will be parsed private static void parseLine(IDictionary dictionary, string line) { if(string.IsNullOrEmpty(line)) { return; } int index = 0; ParserHelper.SkipSpaces(line, ref index); if(index == line.Length) { return; } if(line[index] == '#') { return; } string maskName = parseMaskName(line, ref index); int maskValue = parseMaskValue(line, ref index); // Debug.Log("Setting layer mask " + maskName + " = " + maskValue.ToString()); dictionary[maskName] = maskValue; } /// Parses the name of a layer mask from a line /// Line the layer mask name will be parsed from /// Start index within the line /// The name of the layer mask in the line private static string parseMaskName(string line, ref int index) { if(!char.IsLetter(line, index)) { throw new FileLoadException("Invalid mask name in line: " + line); } int nameStartIndex = index; ++index; ParserHelper.SkipAlphaNumerics(line, ref index); string maskName = line.Substring(nameStartIndex, index - nameStartIndex); ParserHelper.SkipSpaces(line, ref index); if(!ParserHelper.SkipCharacter(line, ':', ref index)) { throw new FileLoadException("Missing ':' in line: " + line); } return maskName; } /// Parses the value of a layer mask from a line /// Line the layer mask value will be parsed from /// Start index within the line /// The value of the layer mask in the line private static int parseMaskValue(string line, ref int index) { int value = 0; int length = line.Length; for(; ; ) { ParserHelper.SkipSpaces(line, ref index); if(char.IsNumber(line, index)) { int numberStart = index; if(ParserHelper.SkipInteger(line, ref index)) { value += int.Parse( line.Substring(numberStart, index - numberStart), CultureInfo.InvariantCulture ); } } else if(char.IsLetter(line, index)) { int nameStart = index; index = line.IndexOf('+', nameStart + 1); if(index == -1) { index = length; } string name = line.Substring(nameStart, index - nameStart).TrimEnd(); int layerIndex = LayerMask.NameToLayer(name); if(layerIndex == -1) { throw new FileLoadException("Unknown layer '" + name + "' in line: " + line); } value += 1 << layerIndex; } else { throw new FileLoadException("Invalid character encountered in line: " + line); } ParserHelper.SkipSpaces(line, ref index); if(index == length) { break; } if(!ParserHelper.SkipCharacter(line, '+', ref index)) { throw new FileLoadException( "Only '+' is allowed for mask combination in line:" + line ); } } return value; } } } // namespace Framework.Layers