internal static void Load() { classes.Clear(); classesByAddress.Clear(); seenClasses.Clear(); // Use two passes so that classesByAddress has all available types which are needed when // calling GCHelper.Find() in the second pass // First pass to fill up classesByAddress collection foreach (KeyValuePair <Type, UMetaPathAttribute> nativeType in UnrealTypes.Native) { Type type = nativeType.Key; UMetaPathAttribute attribute = nativeType.Value; if (type.IsSameOrSubclassOf(typeof(UObject)) || type.IsInterface) { IntPtr classAddress = GetClassAddress(attribute.Path); if (classAddress != IntPtr.Zero) { classesByAddress[classAddress] = type; } } } // It should now be safe to access GCHelper (which is required by the second pass to fill // in the classes collection with the managed UClass objects) GCHelper.Available = true; int unknownCount = 0; // Second pass fill up classes collection foreach (KeyValuePair <IntPtr, Type> classByAddress in classesByAddress) { IntPtr classAddress = classByAddress.Key; Type type = classByAddress.Value; UClass unrealClass = GCHelper.Find <UClass>(classAddress); if (unrealClass != null) { classes[type] = unrealClass; } else { unknownCount++; } } if (unknownCount > 0) { // sync classes/classByAddress if some failed to add to the classes collection foreach (KeyValuePair <IntPtr, Type> classByAddress in new Dictionary <IntPtr, Type>(classesByAddress)) { if (!classes.ContainsKey(classByAddress.Value)) { classesByAddress.Remove(classByAddress.Key); } } } }
internal static IntPtr GetStaticClass(Type type) { if (IsManagedUnrealType(type)) { ManagedUnrealClass baseClass = FindClass(type); if (baseClass != null) { return(baseClass.StaticClass); } baseClass = CreateClass(type); if (baseClass != null) { return(baseClass.StaticClass); } } else { UMetaPathAttribute pathAttribute = type.GetCustomAttribute <UMetaPathAttribute>(); if (pathAttribute != null) { return(UClass.FindClassAddressByPath(pathAttribute.Path)); } } return(IntPtr.Zero); }
internal static void Load(Assembly assembly) { Dictionary <Type, UMetaPathAttribute> nativeTypes; if (UnrealTypes.AssembliesNativeTypes.TryGetValue(assembly, out nativeTypes)) { foreach (KeyValuePair <Type, UMetaPathAttribute> nativeType in nativeTypes) { Type type = nativeType.Key; UMetaPathAttribute attribute = nativeType.Value; if (type.IsSameOrSubclassOf(typeof(UObject)) || type.IsInterface) { IntPtr classAddress = GetClassAddress(attribute.Path); if (classAddress != IntPtr.Zero) { classesByAddress[classAddress] = type; } } } int unknownCount = 0; foreach (KeyValuePair <IntPtr, Type> classByAddress in classesByAddress) { IntPtr classAddress = classByAddress.Key; Type type = classByAddress.Value; UClass unrealClass = GCHelper.Find <UClass>(classAddress); if (unrealClass != null) { classes[type] = unrealClass; } else { unknownCount++; } } if (unknownCount > 0) { // sync classes/classByAddress if some failed to add to the classes collection foreach (KeyValuePair <IntPtr, Type> classByAddress in new Dictionary <IntPtr, Type>(classesByAddress)) { if (!classes.ContainsKey(classByAddress.Value)) { classesByAddress.Remove(classByAddress.Key); } } } } }
internal static IntPtr GetEnum(Type type) { if (IsManagedUnrealType(type)) { } else { UMetaPathAttribute pathAttribute = type.GetCustomAttribute <UMetaPathAttribute>(); if (pathAttribute != null) { return(NativeReflection.FindObject(Native_UEnum.StaticClass(), IntPtr.Zero, pathAttribute.Path, true)); } } return(IntPtr.Zero); }
/// <summary> /// Loads underlying native type info for the given generated type (types tagged with UMetaPath) /// This loads the class address/properties/functions/offsets /// </summary> private static void LoadNative(Type type, UMetaPathAttribute pathAttribute) { UnrealInterfacePool.LoadType(type); bool lazyLoad = LazyLoadingEnabled && !HasCCtorBeenCalled(type); if (!lazyLoad) { // If this is an interface get the default implementation type which will hold the loader method Type targetType = type; if (pathAttribute.InterfaceImpl != null) { targetType = pathAttribute.InterfaceImpl; } MethodInfo method = targetType.GetMethod(CodeGeneratorSettings.LoadNativeTypeMethodName, BindingFlags.Static | BindingFlags.NonPublic); if (method != null) { method.Invoke(null, null); } } }
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); } }
private static void LoadInternal(Assembly thisAssembly, Assembly assembly) { if (processedAssemblies.Contains(assembly)) { return; } processedAssemblies.Add(assembly); bool referencesThisAssembly = false; if (assembly == thisAssembly) { referencesThisAssembly = true; } else { foreach (AssemblyName assemblyName in assembly.GetReferencedAssemblies()) { if (assemblyName.FullName == thisAssembly.FullName) { referencesThisAssembly = true; break; } } } if (!referencesThisAssembly) { return; } List <Type> types = new List <Type>(); Dictionary <Type, UMetaPathAttribute> nativeTypes = new Dictionary <Type, UMetaPathAttribute>(); Dictionary <Type, USharpPathAttribute> managedTypes = new Dictionary <Type, USharpPathAttribute>(); Type assemblyModuleInfoType = null; foreach (Type type in assembly.GetTypes()) { UUnrealTypePathAttribute pathAttribute = type.GetCustomAttribute <UUnrealTypePathAttribute>(false); if (pathAttribute != null && !string.IsNullOrEmpty(pathAttribute.Path)) { USharpPathAttribute sharpPathAttribute = pathAttribute as USharpPathAttribute; if (sharpPathAttribute != null) { AllByPath[pathAttribute.Path] = type; ManagedByPath[pathAttribute.Path] = type; All[type] = sharpPathAttribute; Managed[type] = sharpPathAttribute; types.Add(type); managedTypes[type] = sharpPathAttribute; } else { UMetaPathAttribute metaPathAttribute = pathAttribute as UMetaPathAttribute; if (metaPathAttribute != null) { AllByPath[pathAttribute.Path] = type; NativeByPath[pathAttribute.Path] = type; All[type] = metaPathAttribute; Native[type] = metaPathAttribute; types.Add(type); nativeTypes[type] = metaPathAttribute; } } } if (typeof(ISerializedManagedUnrealModuleInfo).IsAssignableFrom(type) && type != typeof(ISerializedManagedUnrealModuleInfo)) { assemblyModuleInfoType = type; } } if (types.Count > 0) { Assemblies[assembly] = types; AssembliesManagedTypes[assembly] = managedTypes; AssembliesNativeTypes[assembly] = nativeTypes; if (assemblyModuleInfoType != null) { AssemblySerializedModuleInfo[assembly] = assemblyModuleInfoType; } } }