示例#1
0
        private static ValueSetter CreateSetter(TagFieldInfo tagFieldInfo)
        {
            var ownerType = tagFieldInfo.DeclaringType;
            var valueType = tagFieldInfo.FieldType;

            if (ownerType.IsGenericTypeDefinition)
            {
                ownerType = ownerType.MakeGenericType(valueType);
            }

            // Parameter "target", the object on which to set the field `field`.
            var ownerParam = Expression.Parameter(typeof(object));

            // Parameter "value" the value to be set in the `field` on "target".
            var valueParam = Expression.Parameter(typeof(object));

            // Unbox structs to their type, or cast a class to it's type.
            var castTartgetExp = ownerType.IsValueType ?
                                 Expression.Unbox(ownerParam, ownerType) : Expression.Convert(ownerParam, ownerType);

            // Cast the value to its correct type.
            var castValueExp = Expression.Convert(valueParam, valueType);

            // Access the field
            var fieldExp = Expression.Field(castTartgetExp, tagFieldInfo.FieldInfo);

            // Assign the "value" to the `field`.
            var assignExp = Expression.Assign(fieldExp, castValueExp);


            // Compile the whole thing and return.
            var setter = Expression.Lambda <ValueSetter>(assignExp, ownerParam, valueParam).Compile();

            return(setter);
        }
示例#2
0
        private static ValueGetter CreateGetter(TagFieldInfo tagFieldInfo)
        {
            var ownerType = tagFieldInfo.DeclaringType;

            // Parameter "owner", the object on which to get the field value from.
            ParameterExpression ownerParam = Expression.Parameter(typeof(object));

            // Unbox structs to their type, or cast a class to it's type.
            Expression castTartgetExp = ownerType.IsValueType ?
                                        Expression.Unbox(ownerParam, ownerType) : Expression.Convert(ownerParam, ownerType);

            // Access the field
            MemberExpression fieldExp = Expression.Field(castTartgetExp, tagFieldInfo.FieldInfo);

            // Convert field to object Type
            UnaryExpression boxedExp = Expression.Convert(fieldExp, typeof(object));

            var getter = Expression.Lambda <ValueGetter>(boxedExp, ownerParam).Compile();

            return(getter);
        }
示例#3
0
        /// <summary>
        /// Gets the size of a tag-field.
        /// </summary>
        /// <param name="type">The <see cref="Type"/> of the field.</param>
        /// <param name="attr">The <see cref="TagFieldAttribute"/> of the field.</param>
        /// <param name="targetVersion">The <see cref="CacheVersion"/> to target.</param>
        /// <returns></returns>
        public static uint GetFieldSize(Type type, TagFieldAttribute attr, CacheVersion targetVersion)
        {
            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Boolean:
            case TypeCode.SByte:
            case TypeCode.Byte:
                return(0x01);

            case TypeCode.Char:
            case TypeCode.Int16:
            case TypeCode.UInt16:
                return(0x02);

            case TypeCode.Single:
            case TypeCode.Int32:
            case TypeCode.UInt32:
            case TypeCode.Object when attr != null && attr.Flags.HasFlag(TagFieldFlags.Pointer):
            case TypeCode.Object when type == typeof(Tag):
            case TypeCode.Object when type == typeof(CacheAddress):
            case TypeCode.Object when type == typeof(CachedTagInstance) && attr.Flags.HasFlag(TagFieldFlags.Short):
            //case TypeCode.Object when type == typeof(RgbColor):
            case TypeCode.Object when type == typeof(ArgbColor):
            case TypeCode.Object when type == typeof(Point2d):
            case TypeCode.Object when type == typeof(StringId):
            case TypeCode.Object when type == typeof(Angle):
            case TypeCode.Object when type == typeof(VertexShaderReference):
            case TypeCode.Object when type == typeof(PixelShaderReference):
                return(0x04);

            case TypeCode.Double:
            case TypeCode.Int64:
            case TypeCode.UInt64:
            case TypeCode.Object when type == typeof(CachedTagInstance) && targetVersion != CacheVersion.Unknown && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo2Xbox, CacheVersion.Halo2Vista):
            case TypeCode.Object when type == typeof(byte[]) && targetVersion != CacheVersion.Unknown && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo2Xbox, CacheVersion.Halo2Vista):
            case TypeCode.Object when type == typeof(Rectangle2d):
            case TypeCode.Object when type == typeof(RealEulerAngles2d):
            case TypeCode.Object when type == typeof(RealPoint2d):
            case TypeCode.Object when type == typeof(RealVector2d):
            case TypeCode.Object when type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>) && targetVersion != CacheVersion.Unknown && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo2Xbox, CacheVersion.Halo2Vista):
            case TypeCode.Object when type.IsGenericType && type.GetGenericTypeDefinition() == typeof(TagBlock <>) && targetVersion != CacheVersion.Unknown && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo2Xbox, CacheVersion.Halo2Vista):
                return(0x08);

            case TypeCode.Object when type == typeof(RealRgbColor):
            case TypeCode.Object when type == typeof(RealEulerAngles3d):
            case TypeCode.Object when type == typeof(RealPoint3d):
            case TypeCode.Object when type == typeof(RealVector3d):
            case TypeCode.Object when type == typeof(RealPlane2d):
            case TypeCode.Object when type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>) && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo3Retail, CacheVersion.Unknown):
            case TypeCode.Object when type.IsGenericType && type.GetGenericTypeDefinition() == typeof(TagBlock <>) && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo3Retail, CacheVersion.Unknown):
                return(0x0C);

            case TypeCode.Decimal:
            case TypeCode.Object when type == typeof(CachedTagInstance) && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo3Retail, CacheVersion.Unknown):
            case TypeCode.Object when type == typeof(RealArgbColor):
            case TypeCode.Object when type == typeof(RealQuaternion):
            case TypeCode.Object when type == typeof(RealPlane3d):
                return(0x10);

            case TypeCode.Object when type == typeof(byte[]) && CacheVersionDetection.IsBetween(targetVersion, CacheVersion.Halo3Retail, CacheVersion.Unknown):
                return(0x14);

            case TypeCode.Object when type == typeof(RealMatrix4x3):
                return(0x30);

            case TypeCode.Object when type == typeof(DatumIndex):
                return(sizeof(uint));

            case TypeCode.String:
            case TypeCode.Object when type.IsArray:
                return((uint)attr.Length);

            case TypeCode.Object when type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Bounds <>):
                return(TagFieldInfo.GetFieldSize(type.GenericTypeArguments[0], attr, targetVersion) * 2);

            case TypeCode.Object when type.IsEnum:
                return(TagFieldInfo.GetFieldSize(type.GetEnumUnderlyingType(), attr, targetVersion));

            // Assume the field is a structure
            default:
                return(TagStructure.GetTagStructureInfo(type, targetVersion).TotalSize);
            }
        }