Exemple #1
0
        private static void CreateLayoutRecurse(Type type, int baseOffset, List <Layout> layouts, ref int begin,
                                                ref int end, ref int typeHash)
        {
            var fields           = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            var fieldsWithOffset = new FieldData[fields.Length];

            for (int i = 0; i != fields.Length; i++)
            {
                fieldsWithOffset[i].Offset = UnsafeUtility.GetFieldOffset(fields[i]);
                fieldsWithOffset[i].Field  = fields[i];
            }

            Array.Sort(fieldsWithOffset, (a, b) => a.Offset - b.Offset);

            foreach (var fieldWithOffset in fieldsWithOffset)
            {
                var field       = fieldWithOffset.Field;
                var fixedBuffer = GetFixedBufferAttribute(field);
                var offset      = baseOffset + fieldWithOffset.Offset;

                if (fixedBuffer != null)
                {
                    var stride = UnsafeUtility.SizeOf(fixedBuffer.ElementType);
                    for (int i = 0; i < fixedBuffer.Length; ++i)
                    {
                        CreateLayoutRecurse(fixedBuffer.ElementType, offset + i * stride, layouts, ref begin, ref end, ref typeHash);
                    }
                }
                else if (field.FieldType.IsPrimitive || field.FieldType.IsPointer || field.FieldType.IsClass || field.FieldType.IsEnum)
                {
                    CombineHash(ref typeHash, offset, (int)Type.GetTypeCode(field.FieldType));

                    var sizeOf = -1;
                    if (field.FieldType.IsPointer || field.FieldType.IsClass)
                    {
                        sizeOf = UnsafeUtility.SizeOf <PointerSize>();
                    }
                    else if (field.FieldType.IsEnum)
                    {
                        //@TODO: Workaround IL2CPP bug
                        // sizeOf = UnsafeUtility.SizeOf(field.FieldType);
                        sizeOf = UnsafeUtility.SizeOf(field.FieldType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)[0].FieldType);
                    }
                    else
                    {
                        sizeOf = UnsafeUtility.SizeOf(field.FieldType);
                    }

                    if (end != offset)
                    {
                        layouts.Add(new Layout {
                            offset = begin, count = end - begin, Aligned4 = false
                        });
                        begin = offset;
                        end   = offset + sizeOf;
                    }
                    else
                    {
                        end += sizeOf;
                    }
                }
                else
                {
                    CreateLayoutRecurse(field.FieldType, offset, layouts, ref begin, ref end, ref typeHash);
                }
            }
        }
        private static void CreateLayoutRecurse(Type type, int baseOffset, List <Layout> layouts, ref int begin, ref int end, ref int typeHash)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            FieldData[] array  = new FieldData[fields.Length];
            int         index  = 0;

            while (true)
            {
                if (index == fields.Length)
                {
                    Array.Sort <FieldData>(array, (a, b) => a.Offset - b.Offset);
                    foreach (FieldData data in array)
                    {
                        FieldInfo            field = data.Field;
                        FixedBufferAttribute fixedBufferAttribute = GetFixedBufferAttribute(field);
                        int num3 = baseOffset + data.Offset;
                        if (fixedBufferAttribute != null)
                        {
                            int num4 = UnsafeUtility.SizeOf(fixedBufferAttribute.ElementType);
                            int num5 = 0;
                            while (true)
                            {
                                if (num5 >= fixedBufferAttribute.Length)
                                {
                                    break;
                                }
                                CreateLayoutRecurse(fixedBufferAttribute.ElementType, num3 + (num5 * num4), layouts, ref begin, ref end, ref typeHash);
                                num5++;
                            }
                        }
                        else
                        {
                            int isEnum;
                            if ((field.FieldType.IsPrimitive || field.FieldType.IsPointer) || field.FieldType.IsClass)
                            {
                                isEnum = 1;
                            }
                            else
                            {
                                isEnum = (int)field.FieldType.IsEnum;
                            }
                            if (isEnum == 0)
                            {
                                CreateLayoutRecurse(field.FieldType, num3, layouts, ref begin, ref end, ref typeHash);
                            }
                            else
                            {
                                int[] values = new int[] { num3, (int)Type.GetTypeCode(field.FieldType) };
                                CombineHash(ref typeHash, values);
                                int num6 = -1;
                                if (field.FieldType.IsPointer || field.FieldType.IsClass)
                                {
                                    num6 = UnsafeUtility.SizeOf <PointerSize>();
                                }
                                else if (field.FieldType.IsEnum)
                                {
                                    num6 = UnsafeUtility.SizeOf(field.FieldType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)[0].FieldType);
                                }
                                else
                                {
                                    num6 = UnsafeUtility.SizeOf(field.FieldType);
                                }
                                if (end == num3)
                                {
                                    end += num6;
                                }
                                else
                                {
                                    Layout item = new Layout {
                                        offset   = begin,
                                        count    = end - begin,
                                        Aligned4 = false
                                    };
                                    layouts.Add(item);
                                    begin = num3;
                                    end   = num3 + num6;
                                }
                            }
                        }
                    }
                    return;
                }
                array[index].Offset = UnsafeUtility.GetFieldOffset(fields[index]);
                array[index].Field  = fields[index];
                index++;
            }
        }