public Expression(Token token) { base.Token = token; this.Name = token.Match.Groups["name"].Value; if (token.Match.Groups["value"].Success) this.Value = token.Match.Groups["value"].Value; // Set reference ReferenceId = Interlocked.Increment(ref References); }
public RunStatement(Token token) : base(token) { // Load token args // Begin our array builder TokenArgs tokenArgs = new TokenArgs(); // Split the line after the reference call into arguments string[] parts = token.Value.SplitWithQuotes(SplitChars, true); // Skip Run/Include parts = parts.Skip(1).ToArray(); // Set internals FileName = parts[0]; Arguments = parts.Skip(1).ToArray(); }
/// <summary> /// Creates a new Token /// </summary> /// <param name="kind">The kind of this token</param> /// <param name="match">The Match the token is to be generated from</param> /// <param name="file">The con file this token is generating from</param> /// <param name="index">The line number this match is found on</param> /// <returns>The newly created token</returns> internal static Token Create(TokenType kind, Match match, ConFile file, int index) { Token token = new Token() { File = file, Position = match.Index + index, Kind = kind, Match = match, Value = match.Value }; // We only create token args for object property types if (token.Kind == TokenType.ObjectProperty || token.Kind == TokenType.ActiveSwitch) SetTokenArgs(token); return token; }
/// <summary> /// Creates a new instance of <see cref="ConFileObject"/> /// </summary> /// <param name="name">The unique name of this object</param> /// <param name="token"> /// The token which creates this object. If null, an attempt to make a token will be /// made by getting using this objects <see cref="ReferenceType"/>. /// </param> public ConFileObject(string name, Token token = null) { Type type = this.GetType(); // Check for null token! if (token == null) { // === We need a token, so try and create one === // token = CreateToken(name, type, token.File); } // Set object variables this.Name = name; this.File = token.File; base.Token = token; // Build our property Map if (!PropertyMap.ContainsKey(type.Name)) PropertyMap.Add(type.Name, GetPropertyMap(type)); }
/// <summary> /// Creates a new instance of GeometryTemplate with the following attributes /// </summary> /// <param name="tokenArgs">The command line token</param> /// <param name="token">The ConFile token</param> public static ConFileObject Create(Token token) { // Make sure we have the correct number of arguments if (token.TokenArgs.Arguments.Length != 2) { throw new ArgumentException(String.Concat( "Invalid arguments count for GeometryTemplate;", $"Got {token.TokenArgs.Arguments.Length}, Expecting 2." )); } // Extract our arguments string type = token.TokenArgs.Arguments[0]; string name = token.TokenArgs.Arguments[1]; // Ensure this type is supported if (!ObjectTypes.ContainsKey(type)) throw new ParseException("Invalid GeometryTemplate derived type \"" + type + "\".", token); // Create and return our object instance var t = ObjectTypes[type]; return (ConFileObject)Activator.CreateInstance(t, name, token); }
public PlayerControlObject(string Name, Token Token) : base(Name, Token) { }
public GenericFireArm(string Name, Token Token) : base(Name, Token) { }
public GenericProjectile(string name, Token token) : base(name, token) { }
public EntryPoint(string name, Token token) : base(name, token) { }
/// <summary> /// Creates a new instance of Armament /// </summary> /// <param name="Name">The name of this object</param> /// <param name="Token">The parser token</param> public Physical(string Name, Token Token) : base(Name, Token) { }
/// <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; } }
/// <summary> /// Action method for adding child templates to this object /// </summary> /// <param name="token"></param> /// <param name="name"></param> /// <returns></returns> protected virtual ConFileEntry Method_AddTemplate(Token token, string name) { // Get the internal property, and check if templates is null var info = GetProperty("__addTemplate").Value; if (Templates == null) Templates = new ObjectPropertyList<ChildTemplate>("addTemplate", token, info, this); // Create the object template value, and the object property ChildTemplate ct = new ChildTemplate(token.TokenArgs.Arguments.Last(), token); var prop = new ObjectProperty<ChildTemplate>("addTemplate", token, info, this); // We must also manually define the ValueInfo, because ChildTemplate // is NOT a RefernceType object prop.Argument = new ValueInfo<ChildTemplate>(ct); Templates.Items.Add(prop); return prop; }
public ConFileStringEntry(Token token) { Token = token; }
/// <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 Armament /// </summary> /// <param name="Name">The name of this object</param> /// <param name="Token">The parser token</param> public ControlInfo(string Name, Token Token) : base(Name, Token) { }
public Statement(Token token) { base.Token = token; }
public RotationalBundle(string name, Token token) : base(name, token) { }
public ChildTemplate(string name, Token token) : base(name, token) { }
public Wing(string name, Token token) : base(name, token) { }
public Sound(string name, Token token) : base(name, token) { }
/// <summary> /// Converts the value of a <see cref="Token"/> into an array of parameters. /// Any values that are qouted will remain intact /// </summary> /// <param name="tokenValue">The value of the token</param> /// <returns></returns> internal static void SetTokenArgs(Token token) { // Create instance token.TokenArgs = new TokenArgs(); // Break the line into {0 => Template name, 1 => The rest of the line} // We only split into 2 strings, because some values have dots string[] temp = token.Value.Split(new char[] { '.' }, 2); token.TokenArgs.ReferenceType = ReferenceManager.GetReferenceType(temp[0]); // Check for null if (token.TokenArgs.ReferenceType == null) throw new Exception($"Reference call to '{temp[0]}' is not supported"); // Split the line after the reference call into arguments string[] parts = temp[1].SplitWithQuotes(ScriptEngine.SplitChars, true); token.TokenArgs.PropertyName = parts[0]; // Type correction if (token.TokenArgs.ReferenceType.Mappings.ContainsKey(token.TokenArgs.PropertyName)) token.Kind = TokenType.ObjectStart; // Skip the property/function name token.TokenArgs.Arguments = parts.Skip(1).ToArray(); }
public AnimatedBundle(string name, Token token) : base(name, token) { }
public Spring(string name, Token token) : base(name, token) { }
/// <summary> /// Creates a component (Sub Object) for an ObjectTemplate /// </summary> /// <param name="token"></param> /// <param name="comment"></param> protected virtual ConFileEntry Method_CreateComponent(Token token, string name) { Type type = this.GetType(); // Token correction token.Kind = TokenType.Component; // Ensure we have a map of components => property if (!ComponentTypes.ContainsKey(name)) { throw new Exception($"Unregistered component type \"{name}\""); } else if (!ComponentMap.ContainsKey(type.Name)) { throw new Exception($"Object type \"{type.Name}\" does not support Components"); } else if (!ComponentMap[type.Name].ContainsKey(name)) { throw new Exception($"Unsupported Component type \"{name}\" in \"{type.Name}\""); } // Get our field PropertyInfo property = ComponentMap[type.Name][name]; //Type componentType = property.PropertyType.GenericTypeArguments[0]; Type componentType = ComponentTypes[name]; var args = new object[] { name, token }; // Create instances var component = (ConFileObject)Activator.CreateInstance(componentType, args); //var objProperty = ObjectProperty.Create(property, component, token); var objProperty = ObjectProperty.Create(property, this, token); // Use reflection to set the value of the new component instance objProperty.SetValues(new object[] { component }, token); // Set value of this.{name} property.SetValue(this, objProperty); // Add component to file entries by returning it return objProperty; }
/// <summary> /// Creates a new isntance of KitTemplate /// </summary> /// <param name="Name"></param> /// <param name="Token"></param> public KitTemplate(string Name, Token Token) : base(Name, Token) { }
/// <summary> /// Action method for setting the direction and angles of a child object attached /// to the this object by the AddTemplate command. The angle is in terms of /// yaw/pitch/roll. /// </summary> /// <remarks> /// The units used for this parameter are degrees (1 - 360) but you can have /// negative degrees as well. If you define multiple rotations, they happen /// in this order. /// </remarks> /// <param name="token"></param> /// <param name="arg1"></param> protected virtual ConFileEntry Method_SetRotation(Token token, string arg1 = "0/0/0") { // Ensure that we have a child template ChildTemplate item = Templates?.Items?.LastOrDefault()?.Value; if (item == null) { string err = $"SetRotation called on a non-instantiated child object"; Logger.Error(err, token.File, token.Position); throw new Exception(err); } // Get the "SetRotation" field, and make sure the ObjectProperty is not null if (item.SetRotation == null) { PropertyInfo field = item.GetProperty("SetRotation").Value; item.SetRotation = new ObjectProperty<Point3D>("setRotation", token, field, this); token.File.AddProperty(item.SetRotation); } // Set the new value item.SetRotation.SetValue(token); // Don't create an entry! return null; }
/// <summary> /// Creates a new instance of Armament /// </summary> /// <param name="Name">The name of this object</param>/ /// <param name="Token">The parser token</param> public Mobile(string Name, Token Token) : base(Name, Token) { }
/// <summary> /// Converts this <see cref="ConFileObject"/> into the proper script format, /// including the properties that were referenced in the <param name="reference"/> /// parameter. /// </summary> /// <remarks> /// The order in which properties are listed is based on 2 factors: /// 1. The order in which the properties are defined in the C# object file /// 2. The property attribute <see cref="PropertyName.Priority"/> value. /// </remarks> /// <param name="token"> /// IF a token is supplied, we will only include properties that match the token filepath /// with the filepath of the objects properties. /// </param> public string ToFileFormat(Token token) { // Define our type Type objType = this.GetType(); // Make sure we have a token Token tkn = token ?? Token; // Components use our own token! if (typeof(IComponent).IsAssignableFrom(objType)) tkn = Token; // Appy our reference (.create || .active || .activeSafe) line return tkn.Value; }
/// <summary> /// Creates a new instance of KitTemplate with the following attributes /// </summary> /// <param name="tokenArgs">The command line token</param> /// <param name="token">The ConFile token</param> public static KitTemplate Create(Token token) { return new KitTemplate(token.TokenArgs.Arguments.Last(), token); }
/// <summary> /// Creates a new instance of VehicleHud /// </summary> /// <param name="Name"></param> /// <param name="Token"></param> public Kit(string Name, Token Token) : base(Name, Token) { }
/// <summary> /// Creates a new token instance, that can be used to create a new /// instance of this object type. /// </summary> /// <param name="name">The unique name of the object</param> /// <param name="type">The derived type of this object</param> /// <returns></returns> private static Token CreateToken(string name, Type type, ConFile file) { Token token; // NOTE: an exception will be thrown in method if this object // type isnt added to the ReferenceManager var refType = ReferenceManager.GetReferenceType(type); var method = refType.Mappings.FirstOrDefault(); // If we have a Mapping, we assume a non-static object if (method.Key != null && method.Value != null) { // Build a create string... this is pretty Generic // and may not cover custom types very well!!! string input = $"{refType.Name}.{method.Key} {type.Name} {name}"; // Create a new Token token = Tokenizer.Tokenize(input); token.File = file; } else { // Must be a static class, just create a very generic token! token = new Token() { Kind = TokenType.StaticObject, File = file, Value = name, TokenArgs = new TokenArgs() { Arguments = new string[0], ReferenceType = refType } }; } return token; }