#region Arthea License /*********************************************************************** * Arthea MUD by R. Jennings (2007) http://arthea.googlecode.com/ * * By using this code you comply with the Artistic and GPLv2 Licenses. * ***********************************************************************/ #endregion using System; using System.Reflection; using Arthea.Connections.Players; using Arthea.Creation.Attributes; using Arthea.Interfaces; namespace Arthea.Creation { /// <summary> /// Implementation of a class to edit a field. /// </summary> public class OlcField { #region [rgn] Fields (3) private object baseObj; private FieldInfo info; private object obj; #endregion [rgn] #region [rgn] Constructors (1) /// <summary> /// Initializes a new instance of the <see cref="OlcField"/> class. /// </summary> /// <param name="obj">The obj.</param> /// <param name="info">The info.</param> public OlcField(object obj, FieldInfo info) { this.info = info; baseObj = obj; this.obj = info.GetValue(obj); } #endregion [rgn] #region [rgn] Properties (4) /// <summary> /// Gets or sets the base obj. /// </summary> /// <value>The base obj.</value> public object BaseObj { get { return baseObj; } set { baseObj = value; } } /// <summary> /// Gets or sets the info. /// </summary> /// <value>The info.</value> public FieldInfo Info { get { return info; } set { info = value; } } /// <summary> /// Gets the name. /// </summary> /// <value>The name.</value> public string Name { get { return Olc.FieldToWords(info.Name); } } /// <summary> /// Gets or sets the obj. /// </summary> /// <value>The obj.</value> public object Obj { get { return obj; } set { obj = value; } } #endregion [rgn] #region [rgn] Methods (4) // [rgn] Public Methods (3) /// <summary> /// Edits this field. /// </summary> /// <param name="player">The player.</param> /// <param name="argument">The argument.</param> public void Edit(Player player, String argument) { if (CustomEdit(player, argument)) return; try { if (info.FieldType.IsEnum) { Set(Enum.Parse(info.FieldType, argument, true)); } else { Set(Convert.ChangeType(argument.ToString(), info.FieldType)); } player.WriteLine("{0} set to {1}.", new String(info.Name).Capitalize(), argument); } catch (Exception ex) { player.WriteLine("Invalid argument: {0}.", ex.Message); } } /// <summary> /// Gets this instance. /// </summary> public object Get() { PropertyInfo prop = baseObj.GetType().GetProperty(info.Name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); // use a property of field name if it exists if (prop != null) { MethodInfo mi = prop.GetGetMethod(); if (mi != null) { return mi.Invoke(baseObj, new object[] {}); } else { Log.Bug("{0} property is write only.", prop.Name); } } return info.GetValue(baseObj); } /// <summary> /// Sets the specified value. /// </summary> /// <param name="value">The value.</param> public void Set(object value) { PropertyInfo prop = baseObj.GetType().GetProperty(info.Name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); // use a property of field name if it exists if (prop != null) { MethodInfo mi = prop.GetSetMethod(); if (mi != null) { mi.Invoke(baseObj, new object[] {value}); return; } else { Log.Bug("{0} property is read only.", prop.Name); } } info.SetValue(baseObj, value); } // [rgn] Private Methods (1) /// <summary> /// Checks for a custom edit method in this object being edited. /// </summary> /// <param name="player">The player.</param> /// <param name="argument">The argument.</param> /// <returns>true if a custom edit method was executed.</returns> private bool CustomEdit(Player player, String argument) { CustomEditType custEd; if ((obj is CustomEditType) && (custEd = obj as CustomEditType) != null) { custEd.CustomEdit(player, this, argument); return true; } object[] atts = info.GetCustomAttributes(typeof (CustomEditAttribute), false); if (atts.Length == 0) return false; else if (atts.Length > 1) throw new Exception("Ambiguous custom edit attributes."); CustomEditAttribute custAtt = (atts[0] as CustomEditAttribute); if (custAtt == null) throw new Exception("Attribute is not a custom edit attribute."); MethodInfo mi = baseObj.GetType().GetMethod(custAtt.Method, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); if (mi == null) throw new Exception("Custom edit attribute unable to find method."); mi.Invoke(baseObj, new object[] {player, this, argument}); return true; } #endregion [rgn] } }