/// <summary> /// This method is responsible for parsing an object property /// reference line from inside of a .con or .ai file, and converting /// the property into a C# property /// </summary> /// <remarks> /// The type of value is figured out within the method, but only certain types of /// object types can be parsed here. /// </remarks> /// <param name="token">The token for this ObjectProperty</param> /// <param name="objectLevel">Specifies the nested object level for this Property</param> public virtual void Parse(Token token, int objectLevel = 0) { // Seperate our property name and values TokenArgs tokenArgs = token.TokenArgs; string propName = tokenArgs.PropertyNames[objectLevel]; // Fetch our property that we are setting the value to KeyValuePair <string, PropertyInfo> prop = GetProperty(propName); Type propType = prop.Value.PropertyType; bool isCollection = propType.GetInterface("IObjectPropertyCollection") != null; // Get the value that is set var value = prop.Value.GetValue(this); // Is this an object method, or Object Property? if (propType.BaseType.Name == "ObjectMethod") { // Object methods are always instantiated in the object's constructor ObjectMethod method = (ObjectMethod)value; ConFileEntry item = method.Invoke(token); // Add item to the file entry list if (item != null) { token.File?.AddEntry(item, token); } } else { // If the value is null, then we create a new object property instance ObjectProperty obj = (ObjectProperty)value; if (obj == null) { // Create instance and add it to the entries list obj = ObjectProperty.Create(prop.Value, this, token); // Add entry? Property Collections add thier own properties if (!isCollection) { token.File?.AddProperty(obj); } } // Create our instance, and parse obj.SetValue(token, objectLevel); prop.Value.SetValue(this, obj); } }
/// <summary> /// Creates a new instance of an ObjectTemplate /// </summary> /// <param name="Name">The name of this object</param> /// <param name="Token">The ConFile token</param> public ObjectTemplate(string Name, Token Token) : base(Name, Token) { // === Create method instances CreateComponent = new ObjectMethod <string>(Method_CreateComponent); AddTemplate = new ObjectMethod <string>(Method_AddTemplate); SetPosition = new ObjectMethod <string>(Method_SetPosition); SetRotation = new ObjectMethod <string>(Method_SetRotation); // === // Grab this derived type information Type type = this.GetType(); // Map components that are used in this template if (!ComponentMap.ContainsKey(type.Name)) { Dictionary <string, PropertyInfo> properties = new Dictionary <string, PropertyInfo>(); PropertyInfo[] fields = type.GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); // Loop through each property, and search for the custom attribute foreach (PropertyInfo property in fields) { // If the Custom attribute exists, we add it to the Mapping Attribute attribute = Attribute.GetCustomAttribute(property, typeof(Component)); if (attribute != null) { Component fieldAttr = attribute as Component; foreach (string cType in fieldAttr.Types) { properties[cType] = property; } } } // [name] => array of component types that are used in this template ComponentMap[type.Name] = properties; } }