Example #1
0
        public static void Main()
        {
            var referencedByDict  = new Dictionary <Type, List <Type> >();
            var referencesDict    = new Dictionary <Type, List <Type> >();
            var structureRefTypes = new Dictionary <Type, StructureReferenceType>();
            var unsortedTypes     = Assembly.GetExecutingAssembly().GetTypes()
                                    .Where(type => type.Namespace == "UpdateFieldCodeGenerator.Structures");

            foreach (var type in unsortedTypes)
            {
                structureRefTypes[type] = StructureReferenceType.Root;
            }

            foreach (var type in unsortedTypes)
            {
                var allFields = type.GetFields(BindingFlags.Static | BindingFlags.Public)
                                .Where(field => typeof(UpdateField).IsAssignableFrom(field.FieldType))
                                .Select(field => ResolveField(field).Field)
                                .OrderBy(field => field.Order)
                                .Select(field => GetFieldElementType(field.Type, StructureReferenceType.Embedded))
                                .Where(fieldType => fieldType.Item1.Namespace == "UpdateFieldCodeGenerator.Structures");

                foreach (var(fieldType, refType) in allFields)
                {
                    var reference = referencesDict.ComputeIfAbsent(type, k => new List <Type>());
                    if (!reference.Contains(fieldType))
                    {
                        reference.Add(fieldType);
                    }
                    referencedByDict.ComputeIfAbsent(fieldType, k => new List <Type>()).Add(type);
                    structureRefTypes[fieldType] = refType;
                }
            }

            foreach (var referencedBy in referencedByDict)
            {
                referencedBy.Value.Sort((a, b) => GetObjectType(a).CompareTo(GetObjectType(b)));
            }

            var typeList = structureRefTypes.Where(kvp => kvp.Value == StructureReferenceType.Root)
                           .Select(kvp => kvp.Key)
                           .OrderBy(type => GetObjectType(type))
                           .SelectMany(type => (referencesDict.ContainsKey(type) ? referencesDict[type] : Enumerable.Empty <Type>()).Concat(Enumerable.Repeat(type, 1)))
                           .Distinct();

            using (var handlers = new UpdateFieldHandlers())
            {
                handlers.BeforeStructures();
                foreach (var dataType in typeList)
                {
                    var objectType = GetObjectType(referencedByDict.ContainsKey(dataType) ? referencedByDict[dataType].First() : dataType);

                    WriteCreate(dataType, objectType, handlers);
                    WriteUpdate(dataType, objectType, handlers);
                }

                handlers.AfterStructures();
            }
        }
Example #2
0
        private static void WriteUpdate(Type dataType, ObjectType objectType, UpdateFieldHandlers fieldHandler)
        {
            // Update - if the value is a complex structure, it gets its own bits for each field
            // -- dynamic only if sizeof(struct) > 32
            // -- arrays always
            // if next array field is same size, merge it into previous loop
            // Order
            // * bools (as bits, not part of masks)
            // * blz::vectors (CGItemData::m_modifiers)
            // * JamDynamicField.Count
            // * JamDynamicField[].Count (CGActivePlayerData::m_research is a blz::array<JamDynamicField, 1>)
            // * JamDynamicField[].Values (separate loop from count)
            // * JamDynamicField.Values
            // * Values
            // * Arrays
            var allFields = dataType.GetFields(BindingFlags.Static | BindingFlags.Public)
                            .Where(field => typeof(UpdateField).IsAssignableFrom(field.FieldType))
                            .Select(field => ResolveField(field))
                            .GroupBy(field => GetUpdateTypeOrder(field.Field))
                            .Select(group => (group.Key, group.OrderBy(field => field.Field.Order)))
                            .ToDictionary(thing => thing.Key, thing => thing.Item2);

            var hasChangesMask = dataType.GetCustomAttribute <HasChangesMaskAttribute>();

            fieldHandler.OnStructureBegin(dataType, objectType, false, hasChangesMask != null);

            IOrderedEnumerable <(UpdateField Field, string Name)> fieldGroup;

            if (allFields.TryGetValue(UpdateTypeOrder.Bits, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(UpdateTypeOrder.BlzVector, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }

                fieldHandler.FinishControlBlocks();
                fieldHandler.FinishBitPack();
            }

            if (allFields.TryGetValue(UpdateTypeOrder.JamDynamicField, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnDynamicFieldSizeUpdate(Name, Field);
                }

                fieldHandler.FinishControlBlocks();
            }

            if (allFields.TryGetValue(UpdateTypeOrder.JamDynamicFieldArray, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnDynamicFieldSizeUpdate(Name, Field);
                }

                fieldHandler.FinishControlBlocks();
            }

            if (allFields.TryGetValue(UpdateTypeOrder.JamDynamicFieldArray, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (hasChangesMask != null || allFields.ContainsKey(UpdateTypeOrder.Bits) ||
                allFields.ContainsKey(UpdateTypeOrder.JamDynamicField) || allFields.ContainsKey(UpdateTypeOrder.JamDynamicFieldArray))
            {
                fieldHandler.FinishControlBlocks();
                fieldHandler.FinishBitPack();
            }

            if (allFields.TryGetValue(UpdateTypeOrder.JamDynamicField, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup.Where(field => !StructureHasBitFields(field.Field.Type.GenericTypeArguments[0])))
                {
                    fieldHandler.OnField(Name, Field);
                }

                foreach (var(Field, Name) in fieldGroup.Where(field => StructureHasBitFields(field.Field.Type.GenericTypeArguments[0])))
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(UpdateTypeOrder.Default, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(UpdateTypeOrder.Optional, out fieldGroup))
            {
                fieldHandler.FinishControlBlocks();
                fieldHandler.FinishBitPack();

                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnOptionalFieldInitUpdate(Name, Field);
                }
            }

            if (allFields.TryGetValue(UpdateTypeOrder.Optional, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(UpdateTypeOrder.Array, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            fieldHandler.OnStructureEnd(StructureHasBitFields(dataType),
                                        hasChangesMask != null && hasChangesMask.ForceMaskMask);
        }
Example #3
0
        public static void Main()
        {
            var referencedByDict  = new Dictionary <Type, List <Type> >();
            var referencesDict    = new Dictionary <Type, List <Type> >();
            var structureRefTypes = new Dictionary <Type, StructureReferenceType>();
            var unsortedTypes     = Assembly.GetExecutingAssembly().GetTypes()
                                    .Where(type => type.Namespace == "UpdateFieldCodeGenerator.Structures")
                                    .ToList();

            foreach (var type in unsortedTypes)
            {
                structureRefTypes[type] = StructureReferenceType.Root;
            }

            foreach (var type in unsortedTypes)
            {
                var allFields = type.GetFields(BindingFlags.Static | BindingFlags.Public)
                                .Where(field => typeof(UpdateField).IsAssignableFrom(field.FieldType))
                                .Select(field => ResolveField(field).Field)
                                .OrderBy(field => field.Order)
                                .Select(field => GetFieldElementType(field.Type, StructureReferenceType.Embedded))
                                .Where(fieldType => fieldType.Item1.Namespace == "UpdateFieldCodeGenerator.Structures");

                foreach (var(fieldType, refType) in allFields)
                {
                    var reference = referencesDict.ComputeIfAbsent(type, k => new List <Type>());
                    if (!reference.Contains(fieldType))
                    {
                        reference.Add(fieldType);
                    }
                    referencedByDict.ComputeIfAbsent(fieldType, k => new List <Type>()).Add(type);
                    structureRefTypes[fieldType] = refType;
                }
            }

            var typeList = structureRefTypes.Where(kvp => kvp.Value == StructureReferenceType.Root)
                           .Select(kvp => kvp.Key)
                           .OrderBy(type => GetObjectType(type))
                           .ToList();

            foreach (var type in typeList)
            {
                unsortedTypes.Remove(type);
            }

            // add all missed types
            while (unsortedTypes.Count > 0)
            {
                for (var i = 0; i < typeList.Count; ++i)
                {
                    if (referencesDict.TryGetValue(typeList[i], out var referencedTypes))
                    {
                        var insertIndex = i;
                        foreach (var referencedType in referencedTypes)
                        {
                            var unsortedTypeIndex = unsortedTypes.IndexOf(referencedType);
                            if (unsortedTypeIndex == -1)
                            {
                                continue;
                            }

                            typeList.Insert(insertIndex, referencedType);
                            unsortedTypes.RemoveAt(unsortedTypeIndex);
                            i = 0;
                            break;
                        }
                    }
                }
            }

            if (unsortedTypes.Count > 0)
            {
                typeList.AddRange(unsortedTypes);
            }

            using (var handlers = new UpdateFieldHandlers())
            {
                handlers.BeforeStructures();
                foreach (var dataType in typeList)
                {
                    var objectType = structureRefTypes[dataType] == StructureReferenceType.Root
                        ? GetObjectType(dataType)
                        : GetCommonObjectType(GetObjectTypeReferenceRoots(dataType, referencedByDict).Select(t => GetObjectType(t)).ToList());

                    WriteCreate(dataType, objectType, handlers);
                    WriteUpdate(dataType, objectType, handlers);
                }

                handlers.AfterStructures();
            }
        }
Example #4
0
        private static void WriteCreate(Type dataType, ObjectType objectType, UpdateFieldHandlers fieldHandler)
        {
            // Create
            // * In declaration order
            // * JamDynamicField[].Count (CGActivePlayerData::m_research is a blz::array<JamDynamicField, 1>)
            // * JamDynamicField[].Values (separate loop from count)
            // * JamDynamicField.Values
            // * Bits
            // * JamDynamicField.Values that have bits in them
            var allFields = dataType.GetFields(BindingFlags.Static | BindingFlags.Public)
                            .Where(field => typeof(UpdateField).IsAssignableFrom(field.FieldType))
                            .Select(field => ResolveField(field))
                            .GroupBy(field => GetCreateTypeOrder(field.Field))
                            .Select(group => (group.Key, group.OrderBy(field => field.Field.Order)))
                            .ToDictionary(thing => thing.Key, thing => thing.Item2);

            fieldHandler.OnStructureBegin(dataType, objectType, true, dataType.GetCustomAttribute <HasChangesMaskAttribute>() != null);

            IOrderedEnumerable <(UpdateField Field, string Name)> fieldGroup;
            var firstBunchOfFields = Enumerable.Empty <(UpdateField Field, string Name)>();

            if (allFields.TryGetValue(CreateTypeOrder.Default, out fieldGroup))
            {
                firstBunchOfFields = firstBunchOfFields.Concat(fieldGroup);
            }
            if (allFields.TryGetValue(CreateTypeOrder.JamDynamicField, out fieldGroup))
            {
                firstBunchOfFields = firstBunchOfFields.Concat(fieldGroup);
            }
            if (allFields.TryGetValue(CreateTypeOrder.JamDynamicFieldArray, out fieldGroup))
            {
                firstBunchOfFields = firstBunchOfFields.Concat(fieldGroup);
            }
            if (allFields.TryGetValue(CreateTypeOrder.JamDynamicFieldWithBits, out fieldGroup))
            {
                firstBunchOfFields = firstBunchOfFields.Concat(fieldGroup);
            }

            foreach (var(Field, Name) in firstBunchOfFields.OrderBy(field => field.Field.Order))
            {
                if (typeof(DynamicUpdateField).IsAssignableFrom(Field.Type) || (Field.Type.IsArray && typeof(DynamicUpdateField).IsAssignableFrom(Field.Type.GetElementType())))
                {
                    fieldHandler.OnDynamicFieldSizeCreate(Name, Field);
                }
                else
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(CreateTypeOrder.JamDynamicFieldArray, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(CreateTypeOrder.JamDynamicField, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(CreateTypeOrder.DefaultWithBits, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(CreateTypeOrder.ArrayWithBits, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if ((allFields.ContainsKey(CreateTypeOrder.DefaultWithBits) || allFields.ContainsKey(CreateTypeOrder.ArrayWithBits)) &&
                (allFields.ContainsKey(CreateTypeOrder.Bits) || allFields.ContainsKey(CreateTypeOrder.Optional)))
            {
                fieldHandler.FinishControlBlocks();
                fieldHandler.FinishBitPack();
            }

            if (allFields.TryGetValue(CreateTypeOrder.Bits, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(CreateTypeOrder.Optional, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnOptionalFieldInitCreate(Name, Field);
                }
            }

            if (allFields.TryGetValue(CreateTypeOrder.Optional, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            if (allFields.TryGetValue(CreateTypeOrder.JamDynamicFieldWithBits, out fieldGroup))
            {
                foreach (var(Field, Name) in fieldGroup)
                {
                    fieldHandler.OnField(Name, Field);
                }
            }

            fieldHandler.OnStructureEnd(StructureHasBitFields(dataType), false);
        }