#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; using System.Collections.Generic; using System.Globalization; using CodeImp.DoomBuilder.IO; using CodeImp.DoomBuilder.Rendering; using CodeImp.DoomBuilder.Types; using CodeImp.DoomBuilder.ZDoom; #endregion namespace CodeImp.DoomBuilder.Config { public class ArgumentInfo { #region ================== Constants private const int HELPER_SHAPE_ALPHA = 192; //mxd private const int RANGE_SHAPE_ALPHA = 96; //mxd #endregion #region ================== Enums (mxd) public enum ArgumentRenderStyle { NONE, CIRCLE, RECTANGLE, } #endregion #region ================== Variables private readonly string title; private readonly string tooltip; //mxd private readonly bool used; private readonly int type; private EnumList enumlist; private EnumList flagslist; //mxd private readonly object defaultvalue; //mxd private readonly HashSet targetclasses; //mxd private readonly ArgumentRenderStyle renderstyle; //mxd private readonly PixelColor rendercolor; //mxd private readonly PixelColor minrangecolor; //mxd private readonly PixelColor maxrangecolor; //mxd private readonly int minrange; //mxd private readonly int maxrange; //mxd private readonly bool str; // [ZZ] private readonly string titlestr; // [ZZ] #endregion #region ================== Properties public string Title { get { return title; } } public string ToolTip { get { return tooltip; } } //mxd public bool Used { get { return used; } } public int Type { get { return type; } } public HashSet TargetClasses { get { return targetclasses; } } //mxd public EnumList Enum { get { return enumlist; } internal set { enumlist = value; } } public EnumList Flags { get { return flagslist; } internal set { flagslist = value; } } //mxd public object DefaultValue { get { return defaultvalue; } } //mxd public ArgumentRenderStyle RenderStyle { get { return renderstyle; } } //mxd public PixelColor RenderColor { get { return rendercolor; } } //mxd public PixelColor MinRangeColor { get { return minrangecolor; } } //mxd public PixelColor MaxRangeColor { get { return maxrangecolor; } } //mxd public int MinRange { get { return minrange; } } //mxd public int MaxRange { get { return maxrange; } } //mxd public bool Str { get { return str; } } // [ZZ] public string TitleStr { get { return titlestr; } } // [ZZ] #endregion #region ================== Constructor / Disposer // Constructor for argument info from configuration internal ArgumentInfo(Configuration cfg, string argspath, int argindex, bool isstringarg, IDictionary enums) { // Read string argtype = isstringarg ? ".stringarg" : ".arg"; string argpath = argspath + argtype + argindex.ToString(CultureInfo.InvariantCulture); this.used = cfg.SettingExists(argpath); this.title = cfg.ReadSetting(argpath + ".title", (isstringarg ? "String arg. " : "Argument ") + (argindex + 1)); this.tooltip = cfg.ReadSetting(argpath + ".tooltip", string.Empty); //mxd this.type = cfg.ReadSetting(argpath + ".type", 0); this.str = cfg.ReadSetting(argpath + ".str", false); this.titlestr = cfg.ReadSetting(argpath + ".titlestr", this.title); this.defaultvalue = cfg.ReadSetting(argpath + ".default", 0); //mxd. Get rendering hint settings string renderstyle = cfg.ReadSetting(argpath + ".renderstyle", string.Empty); switch(renderstyle.ToLowerInvariant()) { case "circle": this.renderstyle = ArgumentRenderStyle.CIRCLE; break; case "rectangle": this.renderstyle = ArgumentRenderStyle.RECTANGLE; break; default: this.renderstyle = ArgumentRenderStyle.NONE; if(!string.IsNullOrEmpty(renderstyle)) General.ErrorLogger.Add(ErrorType.Error, "\"" + argpath + "\": action argument \"" + this.title + "\" has unknown renderstyle \"" + renderstyle + "\"!"); break; } if(this.renderstyle != ArgumentRenderStyle.NONE) { // Get rendercolor string rendercolor = cfg.ReadSetting(argpath + ".rendercolor", string.Empty); this.rendercolor = General.Colors.InfoLine; if(!string.IsNullOrEmpty(rendercolor) && !ZDTextParser.GetColorFromString(rendercolor, out this.rendercolor)) General.ErrorLogger.Add(ErrorType.Error, "\"" + argpath + "\": action argument \"" + this.title + "\": unable to get rendercolor from value \"" + rendercolor + "\"!"); this.rendercolor.a = HELPER_SHAPE_ALPHA; // Get minrange settings string minrange = cfg.ReadSetting(argpath + ".minrange", string.Empty); if(int.TryParse(minrange, NumberStyles.Integer, CultureInfo.InvariantCulture, out this.minrange) && this.minrange > 0f) { // Get minrangecolor string minrangecolor = cfg.ReadSetting(argpath + ".minrangecolor", string.Empty); this.minrangecolor = General.Colors.Indication; if(!string.IsNullOrEmpty(minrangecolor) && !ZDTextParser.GetColorFromString(minrangecolor, out this.minrangecolor)) General.ErrorLogger.Add(ErrorType.Error, "\"" + argpath + "\": action argument \"" + this.title + "\": unable to get minrangecolor from value \"" + minrangecolor + "\"!"); this.minrangecolor.a = RANGE_SHAPE_ALPHA; } // Get maxrange settings string maxrange = cfg.ReadSetting(argpath + ".maxrange", string.Empty); if(int.TryParse(maxrange, NumberStyles.Integer, CultureInfo.InvariantCulture, out this.maxrange) && this.maxrange > 0f) { // Get minrangecolor string maxrangecolor = cfg.ReadSetting(argpath + ".maxrangecolor", string.Empty); this.maxrangecolor = General.Colors.Indication; if(!string.IsNullOrEmpty(maxrangecolor) && !ZDTextParser.GetColorFromString(maxrangecolor, out this.maxrangecolor)) General.ErrorLogger.Add(ErrorType.Error, "\"" + argpath + "\": action argument \"" + this.title + "\": unable to get maxrangecolor from value \"" + maxrangecolor + "\"!"); this.maxrangecolor.a = RANGE_SHAPE_ALPHA; } // Update tooltip? if(this.minrange > 0f || this.maxrange > 0f) { if(!string.IsNullOrEmpty(this.tooltip)) this.tooltip += Environment.NewLine; if(this.minrange > 0f && this.maxrange > 0f) this.tooltip += "Range: " + this.minrange + " - " + this.maxrange; else if(this.minrange > 0f) this.tooltip += "Minimum range: " + this.minrange; else this.tooltip += "Maximum range: " + this.maxrange; } } //mxd. Check for TargetClass? this.targetclasses = new HashSet(StringComparer.InvariantCultureIgnoreCase); if(this.type == (int)UniversalType.ThingTag) { string s = cfg.ReadSetting(argpath + ".targetclasses", string.Empty); if(!string.IsNullOrEmpty(s)) { foreach(string tclass in s.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)) targetclasses.Add(tclass.Trim()); } } // Determine enum type IDictionary argdic = cfg.ReadSetting(argpath, new Hashtable()); if(argdic.Contains("enum")) { // Enum fully specified? if(argdic["enum"] is IDictionary) { // Create anonymous enum this.enumlist = new EnumList((IDictionary)argdic["enum"]); } else { // Check if referenced enum exists if((argdic["enum"].ToString().Length > 0) && enums.ContainsKey(argdic["enum"].ToString())) { // Get the enum list this.enumlist = enums[argdic["enum"].ToString()]; } else { General.ErrorLogger.Add(ErrorType.Warning, "\"" + argpath + "\" references unknown enumeration \"" + argdic["enum"] + "\"."); } } } //mxd. Determine flags type if(argdic.Contains("flags")) { // Enum fully specified? if(argdic["flags"] is IDictionary) { // Create anonymous enum this.flagslist = new EnumList((IDictionary)argdic["flags"]); } else { // Check if referenced enum exists if((argdic["flags"].ToString().Length > 0) && enums.ContainsKey(argdic["flags"].ToString())) { // Get the enum list this.flagslist = enums[argdic["flags"].ToString()]; } else { General.ErrorLogger.Add(ErrorType.Warning, "\"" + argpath + "\" references unknown flags enumeration \"" + argdic["flags"] + "\"."); } } } if(this.enumlist == null) this.enumlist = new EnumList(); //mxd if(this.flagslist == null) this.flagslist = new EnumList(); //mxd } //mxd. Constructor for an argument info defined in DECORATE // [ZZ] Constructor for an argument info defined in DECORATE/ZScript. reworked. internal ArgumentInfo(ActorStructure actor, int i) { if(!actor.HasPropertyWithValue("$arg" + i)) { used = false; return; } string argtitle = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i)); string tooltip = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "tooltip").Replace("\\n", Environment.NewLine)); int type = actor.GetPropertyValueInt("$arg" + i + "type", 0); string targetclasses = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "targetclasses")); int defaultvalue = actor.GetPropertyValueInt("$arg" + i + "default", 0); string enumstr = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "enum")); string flagstr = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "flags")); string renderstyle = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "renderstyle")); string rendercolor, minrange, maxrange, minrangecolor, maxrangecolor; bool str = (actor.HasProperty("$arg" + i + "str")); string argtitlestr = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "str")); if (string.IsNullOrEmpty(argtitlestr)) argtitlestr = argtitle; if (!string.IsNullOrEmpty(renderstyle)) { rendercolor = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "rendercolor")); minrange = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "minrange")); minrangecolor = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "minrangecolor")); maxrange = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "maxrange")); maxrangecolor = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$arg" + i + "maxrangecolor")); } else { rendercolor = string.Empty; minrange = string.Empty; maxrange = string.Empty; minrangecolor = string.Empty; maxrangecolor = string.Empty; } string actorname = actor.ClassName; IDictionary enums = General.Map.Config.Enums; this.used = true; this.title = argtitle; this.tooltip = tooltip; this.defaultvalue = defaultvalue; this.flagslist = new EnumList(); //mxd this.str = str; this.titlestr = argtitlestr; // Get rendering hint settings switch(renderstyle.ToLowerInvariant()) { case "circle": this.renderstyle = ArgumentRenderStyle.CIRCLE; break; case "rectangle": this.renderstyle = ArgumentRenderStyle.RECTANGLE; break; default: this.renderstyle = ArgumentRenderStyle.NONE; if(!string.IsNullOrEmpty(renderstyle)) General.ErrorLogger.Add(ErrorType.Error, actorname + ": action argument \"" + argtitle + "\" has unknown renderstyle \"" + renderstyle + "\"!"); break; } if(this.renderstyle != ArgumentRenderStyle.NONE) { // Get rendercolor this.rendercolor = General.Colors.InfoLine; if(!string.IsNullOrEmpty(rendercolor) && !ZDTextParser.GetColorFromString(rendercolor, out this.rendercolor)) General.ErrorLogger.Add(ErrorType.Error, actorname + ": action argument \"" + argtitle + "\": unable to get rendercolor from value \"" + rendercolor + "\"!"); this.rendercolor.a = HELPER_SHAPE_ALPHA; // Get minrange settings if(int.TryParse(minrange, NumberStyles.Integer, CultureInfo.InvariantCulture, out this.minrange) && this.minrange > 0f) { // Get minrangecolor this.minrangecolor = General.Colors.Indication; if(!string.IsNullOrEmpty(minrangecolor) && !ZDTextParser.GetColorFromString(minrangecolor, out this.minrangecolor)) General.ErrorLogger.Add(ErrorType.Error, actorname + ": action argument \"" + this.title + "\": unable to get minrangecolor from value \"" + minrangecolor + "\"!"); this.minrangecolor.a = RANGE_SHAPE_ALPHA; } // Get maxrange settings if(int.TryParse(maxrange, NumberStyles.Integer, CultureInfo.InvariantCulture, out this.maxrange) && this.maxrange > 0f) { // Get minrangecolor this.maxrangecolor = General.Colors.Indication; if(!string.IsNullOrEmpty(maxrangecolor) && !ZDTextParser.GetColorFromString(maxrangecolor, out this.maxrangecolor)) General.ErrorLogger.Add(ErrorType.Error, actorname + ": action argument \"" + this.title + "\": unable to get maxrangecolor from value \"" + maxrangecolor + "\"!"); this.maxrangecolor.a = RANGE_SHAPE_ALPHA; } // Update tooltip? if(this.minrange > 0f || this.maxrange > 0f) { if(!string.IsNullOrEmpty(this.tooltip)) this.tooltip += Environment.NewLine + Environment.NewLine; if(this.minrange > 0f && this.maxrange > 0f) this.tooltip += "Expected range: " + this.minrange + " - " + this.maxrange; else if(this.minrange > 0f) this.tooltip += "Minimum: " + this.minrange; else this.tooltip += "Maximum: " + this.maxrange; } } //Check for TargetClass this.targetclasses = new HashSet(StringComparer.InvariantCultureIgnoreCase); if(type == (int)UniversalType.ThingTag) { if(!string.IsNullOrEmpty(targetclasses)) { foreach(string tclass in targetclasses.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)) this.targetclasses.Add(tclass.Trim()); } } // Get argument type if(System.Enum.IsDefined(typeof(UniversalType), type)) { this.type = type; } else { General.ErrorLogger.Add(ErrorType.Error, actorname + ": action argument \"" + argtitle + "\" has unknown type " + type + "!"); this.type = 0; } // Get or create enum if(!string.IsNullOrEmpty(enumstr)) { if(enums.ContainsKey(enumstr.ToLowerInvariant())) { this.enumlist = enums[enumstr.ToLowerInvariant()]; } else { Configuration cfg = new Configuration(); if(cfg.InputConfiguration("enum" + enumstr, true)) { IDictionary argdic = cfg.ReadSetting("enum", new Hashtable()); if(argdic.Keys.Count > 0) this.enumlist = new EnumList(argdic); else General.ErrorLogger.Add(ErrorType.Error, actorname + ": unable to parse explicit enum structure for argument \"" + argtitle + "\"!"); } else { General.ErrorLogger.Add(ErrorType.Error, actorname + ": unable to parse enum structure for argument \"" + argtitle + "\"!"); } } } // Get or create flags if (!string.IsNullOrEmpty(flagstr)) { if (enums.ContainsKey(flagstr.ToLowerInvariant())) { this.flagslist = enums[flagstr.ToLowerInvariant()]; } else { Configuration cfg = new Configuration(); if (cfg.InputConfiguration("flags" + flagstr, true)) { IDictionary argdic = cfg.ReadSetting("flags", new Hashtable()); if (argdic.Keys.Count > 0) this.flagslist = new EnumList(argdic); else General.ErrorLogger.Add(ErrorType.Error, actorname + ": unable to parse explicit enum structure for argument \"" + argtitle + "\"!"); } else { General.ErrorLogger.Add(ErrorType.Error, actorname + ": unable to parse enum structure for argument \"" + argtitle + "\"!"); } } } if (this.enumlist == null) this.enumlist = new EnumList(); if (this.flagslist == null) this.flagslist = new EnumList(); } internal ArgumentInfo(ActorStructure actor, int i, bool stringarg) { if (!actor.HasPropertyWithValue("$stringarg" + i)) { used = false; return; } string argtitle = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$stringarg" + i)); string tooltip = ZDTextParser.StripQuotes(actor.GetPropertyAllValues("$stringarg" + i + "tooltip").Replace("\\n", Environment.NewLine)); this.used = true; this.title = argtitle; this.tooltip = tooltip; } // Constructor for unknown argument info internal ArgumentInfo(int argindex, bool isstringarg) { this.used = false; this.title = (isstringarg ? "String arg. " : "Argument ") + (argindex + 1); this.type = 0; this.enumlist = new EnumList(); this.flagslist = new EnumList(); //mxd this.defaultvalue = 0; //mxd } #endregion #region ================== Methods // This gets the description for an argument value public string GetValueDescription(int value) { // TODO: Use the registered type editor to get the description! return value.ToString(); } #endregion } }