Example #1
0
        /// <summary>
        /// Sets the value(s) of the specified property by name. If the
        /// <see cref="ObjectProperty"/> is null, then a new instance is
        /// created with the inital values provided.
        /// </summary>
        /// <remarks>
        /// This method should only be used when the ObjectProperty is null
        /// outside of the ScriptEngine, since it uses heavy relection.
        /// </remarks>
        /// <param name="propertyName">The <see cref="PropertyName"/> to assign</param>
        /// <param name="values">The values to set in the <see cref="ObjectProperty"/></param>
        public void SetValue(string propertyName, params object[] values)
        {
            // Fetch our property that we are setting the value to
            KeyValuePair <string, PropertyInfo> prop = GetProperty(propertyName);

            // If the first values argument is null, then we remove this property
            if (values == null)
            {
                Remove(prop.Value);
                return;
            }

            // If the value is null, then we create a new object property instance
            var obj = (ObjectProperty)prop.Value.GetValue(this);

            if (obj == null)
            {
                // ===
                // Since the property is null, we must create a con script command.
                // So here, we will use the ReferenceType of this object, and property
                // name to create a fake token, and use that to set the value
                // ===
                StringBuilder builder = new StringBuilder();
                builder.Append($"{Token.TokenArgs.ReferenceType.Name}.{propertyName}");
                foreach (object value in values)
                {
                    builder.Append($" {value}");
                }

                // Create a new Token
                Token token = Tokenizer.Tokenize(builder.ToString());
                token.File = File;

                // Create the ObjectProperty instance, and set this Property to that instance
                obj = ObjectProperty.Create(prop.Value, this, token);

                // Add entry? IObjectPropertyCollection's add thier own properties
                Type type = obj.GetType();
                if (type.GetInterface("IObjectPropertyCollection") == null)
                {
                    Token.File?.AddProperty(obj);
                }
            }

            // Set the new object property values
            obj.SetValues(values);
            prop.Value.SetValue(this, obj);
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <summary>
        /// Converts the object value into the Typed variant of the Specified type parameter,
        /// and returns the <see cref="ValueInfo{T}"/> object for this token property.
        /// This method also sets the value of the <see cref="ValueInfo{T}.Expression"/> field
        /// if this property value is a variable/constant reference.
        /// </summary>
        /// <param name="Value">The current property index value</param>
        /// <returns></returns>
        public static ValueInfo <K> CreateValueInfo <K>(ObjectProperty property, object Value)
        {
            // Grab the type of K
            Type       PropertyType = typeof(K);
            string     strValue     = Value.ToString();
            Expression exp          = null;

            // Check for variable or constant... names must begin with v_ or c_
            if (strValue.StartsWithAny("v_", "c_"))
            {
                // We use the File's expression reference and NOT the Scope,
                // because this object property could be created AFTER the inital
                // parse of the file
                exp   = property.Owner.File.GetExpressionReference(strValue, property);
                Value = exp.Value;
            }

            K newValue = ConvertValue <K>(Value, PropertyType);

            return(new ValueInfo <K>(newValue, exp));
        }
Example #5
0
        /// <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);
        }