/// <summary>
        /// Returns /USharp/Binaries/
        /// </summary>
        public string GetBinDir()
        {
            // This gives "/Binaries/XXXX/" where XXXX is the platform (Win32, Win64, Android, etc)
            string path = FPaths.GetPath(FModuleManager.Get().GetModuleFilename(new FName(ModuleName)));

            // Move this up to "/Binaries/"
            return(Path.Combine(path, "../"));
        }
Beispiel #2
0
 public static FModuleManager Get()
 {
     if (instance == null)
     {
         instance         = new FModuleManager();
         instance.Address = Native_FModuleManager.Get();
     }
     return(instance);
 }
        public void GenerateCodeForModules(UnrealModuleType[] moduleTypes)
        {
            BeginGenerateModules();

            HashSet <string> moduleNamesWhitelistToLower = new HashSet <string>();

            foreach (string moduleName in ModulesNamesWhitelist)
            {
                moduleNamesWhitelistToLower.Add(moduleName.ToLower());
            }

            HashSet <string> moduleNamesBlacklistToLower = new HashSet <string>();

            foreach (string moduleName in ModulesNamesBlacklist)
            {
                moduleNamesBlacklistToLower.Add(moduleName.ToLower());
            }

            Dictionary <UPackage, List <UStruct> >   structsByPackage         = new Dictionary <UPackage, List <UStruct> >();
            Dictionary <UPackage, List <UEnum> >     enumsByPackage           = new Dictionary <UPackage, List <UEnum> >();
            Dictionary <UPackage, List <UFunction> > globalFunctionsByPackage = new Dictionary <UPackage, List <UFunction> >();

            foreach (UStruct unrealStruct in new TObjectIterator <UStruct>())
            {
                if (!unrealStruct.IsA <UFunction>() && CanExportStruct(unrealStruct) && IsAvailableType(unrealStruct))
                {
                    UPackage package = unrealStruct.GetOutermost();
                    if (package != null)
                    {
                        List <UStruct> structs;
                        if (!structsByPackage.TryGetValue(package, out structs))
                        {
                            structsByPackage.Add(package, structs = new List <UStruct>());
                        }
                        structs.Add(unrealStruct);
                    }
                }
            }

            foreach (UEnum unrealEnum in new TObjectIterator <UEnum>())
            {
                if (CanExportEnum(unrealEnum) && IsAvailableType(unrealEnum))
                {
                    UPackage package = unrealEnum.GetOutermost();
                    if (package != null)
                    {
                        List <UEnum> enums;
                        if (!enumsByPackage.TryGetValue(package, out enums))
                        {
                            enumsByPackage.Add(package, enums = new List <UEnum>());
                        }
                        enums.Add(unrealEnum);
                    }
                }
            }

            UClass packageClass = UClass.GetClass <UPackage>();

            foreach (UFunction function in new TObjectIterator <UFunction>())
            {
                UObject outer = function.GetOuter();
                if (outer == null || outer.GetClass() != packageClass)
                {
                    continue;
                }

                if (function.HasAnyFunctionFlags(EFunctionFlags.Delegate | EFunctionFlags.MulticastDelegate))
                {
                    UPackage package = function.GetOutermost();
                    if (package != null)
                    {
                        List <UFunction> functions;
                        if (!globalFunctionsByPackage.TryGetValue(package, out functions))
                        {
                            globalFunctionsByPackage.Add(package, functions = new List <UFunction>());
                        }
                        functions.Add(function);
                    }
                }
                else
                {
                    FMessage.Log(ELogVerbosity.Error, string.Format("Global function which isn't a delegate '{0}'", function.GetName()));
                }
            }

            Dictionary <FName, string> modulePaths = FModulesPaths.FindModulePaths("*");

            // Make sure ModulePaths and ModuleNames are the same. Based on comments FindModules may be changed/removed in the
            // future so we will want to just use FindModulePaths. For now make sure they are synced up.
            FName[] moduleNames = FModuleManager.Get().FindModules("*");
            if (moduleNames.Length != modulePaths.Count)
            {
                FMessage.Log(ELogVerbosity.Warning, string.Format("Module count invalid (update FModulePaths). FindModules:{0} FindModulePaths:{1}",
                                                                  moduleNames.Length, modulePaths.Count));

                List <FName> additionalNames = new List <FName>();
                foreach (KeyValuePair <FName, string> module in modulePaths)
                {
                    if (moduleNames.Contains(module.Key))
                    {
                        FMessage.Log(ELogVerbosity.Warning, "Module: " + module.Key + " - " + module.Value);
                    }
                    else
                    {
                        FMessage.Log(ELogVerbosity.Warning, "Additional module: " + module.Key + " - " + module.Value);
                    }
                }

                List <FName> missingNames = new List <FName>();
                foreach (FName moduleName in moduleNames)
                {
                    if (!modulePaths.ContainsKey(moduleName))
                    {
                        FMessage.Log(ELogVerbosity.Warning, "Missing module: " + moduleName);
                    }
                }
            }


            IPlugin[] plugins = IPluginManager.Instance.GetDiscoveredPlugins();

            SlowTaskSetModuleCount(modulePaths.Count);

            foreach (KeyValuePair <FName, string> modulePath in modulePaths)
            {
                SlowTaskBeginModule(modulePath.Key.PlainName);

                string   moduleName      = modulePath.Key.PlainName;
                string   longPackageName = FPackageName.ConvertToLongScriptPackageName(moduleName);
                UPackage package         = UObject.FindObjectFast <UPackage>(null, new FName(longPackageName), false, false);
                if (package != null)
                {
                    UnrealModuleInfo moduleInfo = new UnrealModuleInfo(package, moduleName, modulePath.Value,
                                                                       UnrealModuleInfo.GetModuleType(moduleName, modulePath.Value, plugins));

                    if (moduleInfo.Type == UnrealModuleType.Unknown)
                    {
                        FMessage.Log(ELogVerbosity.Error, string.Format("Unknown module type on module '{0}' '{1}'",
                                                                        moduleInfo.Name, moduleInfo.Package));
                    }
                    else if (!moduleTypes.Contains(moduleInfo.Type) || moduleNamesBlacklistToLower.Contains(moduleInfo.Name.ToLower()) ||
                             (moduleNamesWhitelistToLower.Count > 0 && !moduleNamesWhitelistToLower.Contains(moduleInfo.Name.ToLower())))
                    {
                        continue;
                    }

                    List <UStruct> structs;
                    if (!structsByPackage.TryGetValue(package, out structs))
                    {
                        structs = new List <UStruct>();
                    }

                    List <UEnum> enums;
                    if (!enumsByPackage.TryGetValue(package, out enums))
                    {
                        enums = new List <UEnum>();
                    }

                    List <UFunction> globalFunctions;
                    if (!globalFunctionsByPackage.TryGetValue(package, out globalFunctions))
                    {
                        globalFunctions = new List <UFunction>();
                    }

                    SlowTaskUpdateTarget(structs.Count + enums.Count + globalFunctions.Count);

                    GenerateCodeForModule(moduleInfo, structs.ToArray(), enums.ToArray(), globalFunctions.ToArray());
                }
            }

            IPlugin.Dispose(plugins);

            EndGenerateModules();
        }
Beispiel #4
0
        /// <summary>
        /// Gets the UClass for the given type
        /// </summary>
        /// <param name="type">The type</param>
        /// <returns>The UClass for the given type</returns>
        public static UClass GetClass(Type type)
        {
            UClass result = null;

            if (classes.TryGetValue(type, out result))
            {
                return(result);
            }

            if (type.IsEnum || type.IsValueType || typeof(IDelegateBase).IsAssignableFrom(type))
            {
                // Find the top-most UClass (UUserDefinedEnum, UEnum, UUserDefinedStruct, UUserStruct, etc)
                // NOTE: This wont contain any useful information about the actual type itself

                IntPtr address = IntPtr.Zero;
                if (type.IsEnum)
                {
                    address = UEnum.GetEnumAddress(type);
                }
                else if (type.IsValueType)
                {
                    address = UScriptStruct.GetStructAddress(type);
                }
                else
                {
                    address = UFunction.GetDelegateSignatureAddress(type);
                }
                if (address != IntPtr.Zero)
                {
                    return(GetClass(address));
                }
                return(null);
            }

            if (!type.IsSameOrSubclassOf(typeof(UObject)) &&
                (!type.IsInterface || !typeof(IInterface).IsAssignableFrom(type)) || type == typeof(IInterface))
            {
                return(null);
            }

            if (seenClasses.Contains(type))
            {
                // Note: GetModuleCount uses a lock
                // TODO: Find some multicast delegate which is called when a module is loaded or a new class type is created.
                // - FModuleManager::Get().OnProcessLoadedObjectsCallback
                if (FModuleManager.Get().GetModuleCount() != lastModuleCount)
                {
                    seenClasses.Clear();
                }
                else
                {
                    return(null);
                }
            }

            if (!seenClasses.Contains(type))
            {
                seenClasses.Add(type);

                UMetaPathAttribute pathAttribute;
                if (UnrealTypes.Native.TryGetValue(type, out pathAttribute))
                {
                    IntPtr classAddress = GetClassAddress(pathAttribute.Path);
                    if (classAddress == IntPtr.Zero)
                    {
                        // Fallback if this class isn't loaded yet. TODO: Check if this is the correct method to call.
                        classAddress = NativeReflection.LoadObject(Classes.UClass, IntPtr.Zero, pathAttribute.Path);
                    }
                    if (classAddress != IntPtr.Zero)
                    {
                        UClass unrealClass = GCHelper.Find <UClass>(classAddress);
                        if (unrealClass != null)
                        {
                            classesByAddress[classAddress] = type;
                            classes[type] = unrealClass;
                            return(unrealClass);
                        }
                    }
                }
            }

            return(null);
        }