コード例 #1
0
        private void GenerateCodeForEnum(UnrealModuleInfo module, UEnum unrealEnum)
        {
            UnrealModuleType moduleAssetType;
            string           currentNamespace = GetModuleNamespace(unrealEnum, out moduleAssetType);
            List <string>    namespaces       = GetDefaultNamespaces();

            CSharpTextBuilder builder = new CSharpTextBuilder(Settings.IndentType);

            if (!string.IsNullOrEmpty(currentNamespace))
            {
                builder.AppendLine("namespace " + currentNamespace);
                builder.OpenBrace();
            }

            GenerateCodeForEnum(module, builder, unrealEnum);

            if (!string.IsNullOrEmpty(currentNamespace))
            {
                builder.CloseBrace();
            }

            builder.InsertNamespaces(currentNamespace, namespaces, Settings.SortNamespaces);

            OnCodeGenerated(module, moduleAssetType, GetTypeName(unrealEnum), unrealEnum.GetPathName(), builder);
        }
コード例 #2
0
        private string GetEnumValuePrefix(UEnum unrealEnum)
        {
            string enumPrefix;

            if (enumValuePrefixCache.TryGetValue(unrealEnum.GetPathName(), out enumPrefix))
            {
                return(enumPrefix);
            }

            GetEnumValues(unrealEnum, false);

            if (enumValuePrefixCache.TryGetValue(unrealEnum.GetPathName(), out enumPrefix))
            {
                return(enumPrefix);
            }
            return(null);
        }
コード例 #3
0
 private bool IsBlueprintVisibleEnum(UEnum unrealEnum)
 {
     if (forceExportEnums.Contains(unrealEnum.GetPathName()))
     {
         return(true);
     }
     return(unrealEnum.GetBoolMetaData(MDEnum.BlueprintType));
 }
コード例 #4
0
        private bool CanExportEnum(UEnum unrealEnum)
        {
            // Skip enums which are already defined in this project
            if (projectDefinedTypes.ContainsKey(unrealEnum.GetPathName()))
            {
                return(false);
            }

            return(true);
        }
コード例 #5
0
        private List <EnumValueInfo> GetEnumValues(UEnum unrealEnum, bool getDocumentation)
        {
            int  valueCount      = unrealEnum.NumEnums();
            bool isBlueprintEnum = unrealEnum.IsA <UUserDefinedEnum>();

            List <EnumValueInfo> enumValues = new List <EnumValueInfo>(valueCount);

            // Try to identify a common prefix of the form PRE_, so we can strip it from all values.
            // We'll only strip it if it's present on all values not explicitly skipped.
            string commonPrefix      = null;
            int    commonPrefixCount = 0;
            int    skippedValueCount = 0;

            int numMax = 0;

            if (Settings.RemoveEnumMAX)
            {
                // Skip all ending "MAX" values (Some enums have duplicate MAX (DORN_MAX / ENetDormancy_MAX))
                for (int i = valueCount - 1; i >= 0; --i)
                {
                    string rawName = GetEnumValueName(unrealEnum, i);

                    // Using case sensitive here to avoid removing genuine "Max" values (still may be removing genuine "MAX" values)
                    if (rawName.EndsWith("MAX"))
                    {
                        ++numMax;
                        ++skippedValueCount;

                        // Duplicate MAX should be "XXX_MAX" for last value and "MAX" for second to last value
                        if (i < valueCount - 1 || !rawName.EndsWith("_MAX"))
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //if (numMax > 1)
            //{
            //    FMessage.Log("Duplicate MAX in enum " + unrealEnum.GetPathName());
            //}

            for (int i = 0; i < valueCount - numMax; ++i)
            {
                string rawName = GetEnumValueName(unrealEnum, i);

                EnumValueInfo enumValue = new EnumValueInfo();
                enumValue.Index       = i;
                enumValue.Value       = unrealEnum.GetValueByIndex(i);
                enumValue.Name        = rawName;
                enumValue.DisplayName = MakeValidName(unrealEnum.GetDisplayNameTextStringByIndex(i));
                if (getDocumentation)
                {
                    enumValue.DocCommentSummary = unrealEnum.GetToolTipByIndex(i);
                }
                enumValues.Add(enumValue);

                // We can skip all of the common prefix checks for enums that are already namespaced in C++.
                // In the cases where a namespaced enum does have a common prefix for its values, it doesn't
                // match the PRE_* pattern, and it's generally necessary for syntactic reasons,
                // i.e. Touch1, Touch2, and so on in ETouchIndex.
                if (unrealEnum.GetCppForm() == UEnum.ECppForm.Regular)
                {
                    // A handful of enums have bad values named this way in C++.
                    if (rawName.StartsWith("TEMP_BROKEN"))
                    {
                        ++skippedValueCount;
                    }
                    // UHT inserts spacers for sparse enums.  Since we're omitting the _MAX value, we'll
                    // still export these to ensure that C# reflection gives an accurate value count, but
                    // don't hold them against the common prefix count.
                    else if (rawName.StartsWith("UnusedSpacer_"))
                    {
                        ++skippedValueCount;
                    }
                    // Infer the prefix from the first unskipped value.
                    else if (string.IsNullOrEmpty(commonPrefix))
                    {
                        int underscorePos = rawName.IndexOf("_");
                        if (underscorePos >= 0)
                        {
                            commonPrefix = rawName.Substring(0, underscorePos + 1);
                            ++commonPrefixCount;
                        }
                    }
                    else if (rawName.StartsWith(commonPrefix))
                    {
                        ++commonPrefixCount;
                    }
                }
            }

            if (valueCount != (commonPrefixCount + skippedValueCount))
            {
                //if (!string.IsNullOrEmpty(commonPrefix))
                //{
                //    FMessage.Log(string.Format("Rejecting common prefix '{0}' for '{1}' ({2}). ValueCount={3}, CommonPrefixCount={4}, SkippedValueCount={5}",
                //        commonPrefix, unrealEnum.GetName(), unrealEnum.GetFName().DisplayIndex, valueCount, commonPrefixCount, skippedValueCount));
                //}

                commonPrefix = null;
            }

            foreach (EnumValueInfo enumValue in enumValues)
            {
                if (!string.IsNullOrEmpty(commonPrefix))
                {
                    enumValue.Name = enumValue.Name.RemoveFromStart(commonPrefix);
                }

                //one enum has a member called "float" which isn't valid in C#. That said, C# enum values should be PascalCase anyway, so just uppercase it.
                if (char.IsLower(enumValue.Name[0]))
                {
                    enumValue.Name = char.ToUpperInvariant(enumValue.Name[0]) + enumValue.Name.Substring(1);
                }

                if (char.IsDigit(enumValue.Name[0]))
                {
                    enumValue.Name = "_" + enumValue.Name;
                }
            }

            // Update the enum prefix cache for lookup with default function params
            enumValuePrefixCache[unrealEnum.GetPathName()] = commonPrefix;

            return(enumValues);
        }
コード例 #6
0
ファイル: UProperty.cs プロジェクト: yimengfan/USharp
        // Move this somewhere else? Where would this be more appropriate?
        public static Type GetTypeFromProperty(UProperty prop)
        {
            if (prop == null)
            {
                return(null);
            }

            switch (prop.PropertyType)
            {
            case EPropertyType.Bool:
                return(typeof(bool));

            case EPropertyType.Int8:
                return(typeof(sbyte));

            case EPropertyType.Byte:
                return(typeof(byte));

            case EPropertyType.Int16:
                return(typeof(short));

            case EPropertyType.UInt16:
                return(typeof(ushort));

            case EPropertyType.Int:
                return(typeof(int));

            case EPropertyType.UInt32:
                return(typeof(uint));

            case EPropertyType.Int64:
                return(typeof(long));

            case EPropertyType.UInt64:
                return(typeof(ulong));

            case EPropertyType.Float:
                return(typeof(float));

            case EPropertyType.Double:
                return(typeof(double));

            case EPropertyType.Enum:
            {
                UEnum unrealEnum = (prop as UEnumProperty).GetEnum();
                if (unrealEnum == null)
                {
                    return(null);
                }

                Type enumType;
                ManagedUnrealModuleInfo.AllKnownUnrealTypes.TryGetValue(unrealEnum.GetPathName(), out enumType);
                return(enumType);
            }

            case EPropertyType.Str:
                return(typeof(string));

            case EPropertyType.Name:
                return(typeof(FName));

            case EPropertyType.Text:
                return(typeof(FText));

            case EPropertyType.Interface:
            {
                UClass unrealClassInterface = (prop as UInterfaceProperty).InterfaceClass;
                if (unrealClassInterface == null)
                {
                    return(null);
                }

                Type interfaceType;
                ManagedUnrealModuleInfo.AllKnownUnrealTypes.TryGetValue(unrealClassInterface.GetPathName(), out interfaceType);
                return(interfaceType);
            }

            case EPropertyType.Struct:
            {
                UScriptStruct unrealStruct = (prop as UStructProperty).Struct;
                if (unrealStruct == null)
                {
                    return(null);
                }

                Type structType;
                ManagedUnrealModuleInfo.AllKnownUnrealTypes.TryGetValue(unrealStruct.GetPathName(), out structType);
                return(structType);
            }

            case EPropertyType.Class:
            case EPropertyType.Object:
            case EPropertyType.LazyObject:
            case EPropertyType.WeakObject:
            case EPropertyType.SoftClass:
            case EPropertyType.SoftObject:
            {
                UClass objectClass = (prop as UObjectPropertyBase).PropertyClass;
                switch (prop.PropertyType)
                {
                case EPropertyType.Class:
                    objectClass = (prop as UClassProperty).MetaClass;
                    break;

                case EPropertyType.SoftClass:
                    objectClass = (prop as USoftClassProperty).MetaClass;
                    break;
                }

                Type type = null;
                if (objectClass != null)
                {
                    // Could use UClass.GetType but using AllKnownUnrealTypes for slightly more coverage
                    // UClass.GetType(objectClass)
                    ManagedUnrealModuleInfo.AllKnownUnrealTypes.TryGetValue(objectClass.GetPathName(), out type);
                }

                if (type == null)
                {
                    //classType = typeof(UObject);// Fall back to UObject? Return null?
                    return(null);
                }
                switch (prop.PropertyType)
                {
                case EPropertyType.Class: return(typeof(TSubclassOf <>).MakeGenericType(type));

                case EPropertyType.LazyObject: return(typeof(TLazyObject <>).MakeGenericType(type));

                case EPropertyType.WeakObject: return(typeof(TWeakObject <>).MakeGenericType(type));

                case EPropertyType.SoftClass: return(typeof(TSoftClass <>).MakeGenericType(type));

                case EPropertyType.SoftObject: return(typeof(TSoftObject <>).MakeGenericType(type));

                case EPropertyType.Object: return(type);
                }
                return(type);
            }

            case EPropertyType.Delegate:
            case EPropertyType.MulticastDelegate:
                Type      delegateType  = null;
                UFunction signatureFunc = null;
                if (prop.PropertyType == EPropertyType.Delegate)
                {
                    signatureFunc = (prop as UDelegateProperty).SignatureFunction;
                }
                else if (prop.PropertyType == EPropertyType.MulticastDelegate)
                {
                    signatureFunc = (prop as UMulticastDelegateProperty).SignatureFunction;
                }
                if (signatureFunc != null)
                {
                    if (ManagedUnrealModuleInfo.AllKnownUnrealTypes.TryGetValue(signatureFunc.GetPathName(), out delegateType))
                    {
                        if (prop.PropertyType == EPropertyType.Delegate)
                        {
                            if (!delegateType.IsSameOrSubclassOfGeneric(typeof(FDelegate <>)))
                            {
                                delegateType = null;
                            }
                        }
                        else if (prop.PropertyType == EPropertyType.MulticastDelegate)
                        {
                            if (!delegateType.IsSameOrSubclassOfGeneric(typeof(FMulticastDelegate <>)))
                            {
                                delegateType = null;
                            }
                        }
                    }
                }
                return(delegateType);

            case EPropertyType.Array:
            {
                UArrayProperty arrayProp = prop as UArrayProperty;
                Type           innerType = GetTypeFromProperty(arrayProp.Inner);
                if (innerType != null)
                {
                    // Possibly handle IReadOnlyList?
                    return(typeof(IList <>).MakeGenericType(innerType));
                }
                return(null);
            }

            case EPropertyType.Set:
            {
                USetProperty setProp   = prop as USetProperty;
                Type         innerType = GetTypeFromProperty(setProp.ElementProp);
                if (innerType != null)
                {
                    return(typeof(ISet <>).MakeGenericType(innerType));
                }
                return(null);
            }

            case EPropertyType.Map:
            {
                UMapProperty mapProp   = prop as UMapProperty;
                Type         keyType   = GetTypeFromProperty(mapProp.KeyProp);
                Type         valueType = GetTypeFromProperty(mapProp.ValueProp);
                if (keyType != null && valueType != null)
                {
                    // Possibly handle IReadOnlyDictionary?
                    return(typeof(IDictionary <,>).MakeGenericType(keyType, valueType));
                }
                return(null);
            }
            }

            return(null);
        }