Esempio n. 1
0
        // 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);
        }
Esempio n. 2
0
        internal static void GenerateCode(string[] args)
        {
            try
            {
                bool invalidArgs = false;

                if (args.Length > 0)
                {
                    CodeGenerator codeGenerator = null;

                    switch (args[0])
                    {
                    /*case "blueprints":
                     *  AssetLoadMode loadMode = AssetLoadMode.Game;
                     *  bool clearAssetCache = false;
                     *  bool skipLevels = false;
                     *  if (args.Length > 1)
                     *  {
                     *      switch (args[1])
                     *      {
                     *          case "game":
                     *              loadMode = CodeGenerator.AssetLoadMode.Game;
                     *              break;
                     *          case "gameplugins":
                     *              loadMode = CodeGenerator.AssetLoadMode.GamePlugins;
                     *              break;
                     *          case "engine":
                     *              loadMode = CodeGenerator.AssetLoadMode.Engine;
                     *              break;
                     *          case "engineplugins":
                     *              loadMode = CodeGenerator.AssetLoadMode.EnginePlugins;
                     *              break;
                     *          case "all":
                     *              loadMode = CodeGenerator.AssetLoadMode.All;
                     *              break;
                     *      }
                     *  }
                     *  if (args.Length > 2)
                     *  {
                     *      bool.TryParse(args[2], out clearAssetCache);
                     *  }
                     *  if (args.Length > 3)
                     *  {
                     *      bool.TryParse(args[3], out skipLevels);
                     *  }
                     *  codeGenerator = new CodeGenerator();
                     *  codeGenerator.GenerateCodeForBlueprints(loadMode, clearAssetCache, skipLevels);
                     *  break;*/

                    case "game":
                        codeGenerator = new CodeGenerator();
                        codeGenerator.GenerateCodeForModules(new UnrealModuleType[] { UnrealModuleType.Game });
                        break;

                    case "gameplugins":
                        codeGenerator = new CodeGenerator();
                        codeGenerator.GenerateCodeForModules(new UnrealModuleType[] { UnrealModuleType.GamePlugin });
                        break;

                    case "modules":
                        // Engine modules (whitelisted)
                        codeGenerator = new CodeGenerator();
                        //codeGenerator.Settings.ExportMode = CodeGeneratorSettings.CodeExportMode.All;
                        //codeGenerator.Settings.ExportAllFunctions = true;
                        //codeGenerator.Settings.ExportAllProperties = true;
                        string whitelistFile = Path.Combine(codeGenerator.Settings.GetManagedPluginSettingsDir(), "ModulesWhitelist.txt");
                        string blacklistFile = Path.Combine(codeGenerator.Settings.GetManagedPluginSettingsDir(), "ModulesBlacklist.txt");
                        if (File.Exists(whitelistFile))
                        {
                            foreach (string line in File.ReadAllLines(whitelistFile))
                            {
                                if (!string.IsNullOrEmpty(line))
                                {
                                    codeGenerator.ModulesNamesWhitelist.Add(line);
                                }
                            }
                        }
                        if (File.Exists(blacklistFile))
                        {
                            foreach (string line in File.ReadAllLines(blacklistFile))
                            {
                                if (!string.IsNullOrEmpty(line))
                                {
                                    codeGenerator.ModulesNamesBlacklist.Add(line);
                                }
                            }
                        }
                        codeGenerator.GenerateCodeForEngineModules();
                        break;

                    case "all_modules":
                        codeGenerator = new CodeGenerator();
                        codeGenerator.GenerateCodeForAllModules();
                        break;

                    case "engine_modules":
                        codeGenerator = new CodeGenerator();
                        codeGenerator.GenerateCodeForEngineModules();
                        break;

                    case "module":
                        if (args.Length > 1)
                        {
                            bool forceExport = false;
                            if (args.Length > 2)
                            {
                                bool.TryParse(args[2], out forceExport);
                            }

                            codeGenerator = new CodeGenerator();
                            // Tests / using these for types for use in this lib
                            //codeGenerator.Settings.CheckUObjectDestroyed = false;
                            //codeGenerator.Settings.GenerateIsValidSafeguards = false;
                            //codeGenerator.Settings.MergeEnumFiles = false;
                            if (forceExport)
                            {
                                codeGenerator.Settings.ExportMode          = CodeGeneratorSettings.CodeExportMode.All;
                                codeGenerator.Settings.ExportAllFunctions  = true;
                                codeGenerator.Settings.ExportAllProperties = true;
                            }
                            codeGenerator.GenerateCodeForModule(args[1], true);
                        }
                        else
                        {
                            invalidArgs = true;
                        }
                        break;

                    case "check_flags":
                    {
                        // This checks the flags for manually wrapped types
                        Assembly[] assemblies = new Assembly[2];
                        assemblies[0] = Assembly.GetExecutingAssembly();
                        UClass engineClass = UClass.GetClass("/Script/Engine.Engine");
                        if (engineClass != null)
                        {
                            Type type = UClass.GetType(engineClass);
                            if (type == null)
                            {
                                FMessage.Log(ELogVerbosity.Warning, "Failed to fine UEngine type");
                            }
                            else
                            {
                                assemblies[1] = type.Assembly;
                            }
                        }
                        else
                        {
                            FMessage.Log(ELogVerbosity.Warning, "Failed to fine UEngine class");
                        }
                        foreach (Assembly assembly in assemblies)
                        {
                            if (assembly == null)
                            {
                                continue;
                            }
                            foreach (Type type in assembly.GetTypes())
                            {
                                UMetaPathAttribute pathAttribute = type.GetCustomAttribute <UMetaPathAttribute>(false);
                                if (pathAttribute != null && !string.IsNullOrEmpty(pathAttribute.Path))
                                {
                                    uint oldFlags = 0;
                                    if (type.IsSameOrSubclassOf(typeof(UObject)))
                                    {
                                        UClassAttribute classAttribute = type.GetCustomAttribute <UClassAttribute>(false);
                                        if (classAttribute != null)
                                        {
                                            oldFlags = (uint)classAttribute.Flags;
                                        }

                                        UClass unrealClass = UClass.GetClass(pathAttribute.Path);
                                        if (unrealClass != null)
                                        {
                                            if (oldFlags != (uint)unrealClass.ClassFlags)
                                            {
                                                FMessage.Log("old: 0x" + oldFlags.ToString("X8") + " new: 0x" +
                                                             ((uint)unrealClass.ClassFlags).ToString("X8") + " path: " + unrealClass.GetPathName());
                                            }
                                        }
                                    }
                                    else
                                    {
                                        UStructAttribute structAttribute = type.GetCustomAttribute <UStructAttribute>(false);
                                        if (structAttribute != null)
                                        {
                                            oldFlags = (uint)structAttribute.Flags;
                                        }

                                        UScriptStruct unrealStruct = UScriptStruct.GetStruct(pathAttribute.Path);
                                        if (unrealStruct != null)
                                        {
                                            if (oldFlags != (uint)unrealStruct.StructFlags)
                                            {
                                                FMessage.Log("old: 0x" + oldFlags.ToString("X8") + " new: 0x" +
                                                             ((uint)unrealStruct.StructFlags).ToString("X8") + " path: " + unrealStruct.GetPathName());
                                            }
                                        }
                                    }
                                }
                            }
                            FMessage.Log("--------");
                        }
                    }
                    break;

                    case "compile":
                        CompileGeneratedCode();
                        break;

                    default:
                        invalidArgs = true;
                        break;
                    }
                }
                else
                {
                    invalidArgs = true;
                }

                if (invalidArgs)
                {
                    FMessage.Log(ELogVerbosity.Warning, "Invalid input. Provide one of the following: game, gameplugins, modules, module [ModuleName], compile");
                }
            }
            catch (Exception e)
            {
                FMessage.Log(ELogVerbosity.Error, "Generate code failed. Error: \n" + e);
            }
        }