/// <summary> /// Synchronously load (if necessary) and return the asset object represented by this asset ptr /// </summary> public UClass LoadSynchronous() { UObject asset = softObject.Value; if (asset == null || IsPending) { asset = softObject.LoadSynchronous(); } UClass unrealClass = asset as UClass; if (unrealClass == null || !unrealClass.IsChildOf <T>()) { return(null); } return(unrealClass); }
public void SetClass(UClass unrealClass) { if (unrealClass != null) { if (!unrealClass.IsChildOf <T>()) { throw new Exception("TSubclassOf - tried to set class with the wrong target class type. Expected:" + typeof(T) + " Actual:" + UClass.GetType(unrealClass.Address)); } subclassOf.ClassAddress = unrealClass.Address; } else { subclassOf.ClassAddress = IntPtr.Zero; } }
public void GenerateCodeForBlueprints(AssetLoadMode loadMode, bool clearAssetCache, bool skipLevels) { BeginGenerateModules(); string projectPath = FPaths.ProjectFilePath; string projectName = FPaths.GetBaseFilename(projectPath); UnrealModuleInfo module = new UnrealModuleInfo(null, projectName, projectPath); BeginGenerateModule(module); UClass worldClass = GCHelper.Find <UClass>(Classes.UWorld); AssetCache assetCache = new AssetCache(this); if (!clearAssetCache) { assetCache.Load(); } List <string> assetBlacklist = LoadAssetBlacklist(); AssetLogClear(); AssetLogLine("Load assets {0}", DateTime.Now); bool registeredCrashHandler = false; if (Settings.CatchCrashOnAssetLoading) { FCoreDelegates.OnHandleSystemError.Bind(OnAssetLoadingCrash); registeredCrashHandler = true; } using (FARFilter filter = new FARFilter()) { filter.RecursiveClasses = true; filter.ClassNames.Add(UClass.GetClass <UBlueprint>().GetFName()); filter.ClassNames.Add(UClass.GetClass <UBlueprintGeneratedClass>().GetFName()); filter.ClassNames.Add(UClass.GetClass <UUserDefinedStruct>().GetFName()); filter.ClassNames.Add(UClass.GetClass <UUserDefinedEnum>().GetFName()); if (!skipLevels && worldClass != null) { filter.ClassNames.Add(worldClass.GetFName()); } List <FAssetData> assets = FAssetData.Load(filter); SlowTaskSetModuleCount(1); SlowTaskBeginModule("Blueprints", assets.Count); foreach (FAssetData asset in assets) { SlowTaskStep(null); string assetFileName, assetFileNameError; if (!asset.TryGetFilename(out assetFileName, out assetFileNameError)) { FMessage.Log(string.Format("FAssetData.TryGetFilename failed. ObjectPath:'{0}' reason:'{1}'", asset.ObjectPath.ToString(), assetFileNameError)); continue; } bool isEngineAsset = FPaths.IsSameOrSubDirectory(FPaths.EngineContentDir, FPaths.GetPath(assetFileName)); if (loadMode != AssetLoadMode.All) { if ((isEngineAsset && loadMode != AssetLoadMode.Engine) || (!isEngineAsset && loadMode != AssetLoadMode.Game)) { continue; } } if (!assetCache.HasAssetChanged(asset, assetFileName)) { if (Settings.LogAssetLoadingVerbose) { AssetLogLine("'{0}' unchanged", assetFileName); } continue; } // Log that we are loading this asset so we know which assets crash on load AssetLog("'{0}' - ", asset.ObjectPath.ToString()); if (assetBlacklist.Contains(asset.ObjectPath.ToString())) { AssetLogLine("blacklisted"); continue; } loadingAsset = asset.ObjectPath.ToString(); UObject obj = asset.GetAsset(); loadingAsset = null; UClass unrealClass = asset.GetClass(); if (obj == null || unrealClass == null) { AssetLogLine("null"); continue; } AssetLogLine("done"); if (unrealClass.IsChildOf <UBlueprint>()) { UBlueprint blueprint = obj as UBlueprint; if (blueprint != null) { UBlueprintGeneratedClass blueprintGeneratedClass = blueprint.GeneratedClass as UBlueprintGeneratedClass; if (blueprintGeneratedClass != null) { GenerateCodeForStruct(module, blueprintGeneratedClass); } } } else if (unrealClass.IsChildOf <UBlueprintGeneratedClass>()) { UBlueprintGeneratedClass blueprintGeneratedClass = obj as UBlueprintGeneratedClass; if (blueprintGeneratedClass != null) { GenerateCodeForStruct(module, blueprintGeneratedClass); } } else if (unrealClass.IsChildOf <UUserDefinedStruct>()) { UUserDefinedStruct unrealStruct = obj as UUserDefinedStruct; if (unrealStruct != null) { GenerateCodeForStruct(module, unrealStruct); } } else if (unrealClass.IsChildOf <UUserDefinedEnum>()) { UUserDefinedEnum unrealEnum = obj as UUserDefinedEnum; if (unrealEnum != null) { GenerateCodeForEnum(module, unrealEnum); } } else if (unrealClass.IsChildOf(worldClass)) { TArrayUnsafeRef <UObject> levels = new TArrayUnsafeRef <UObject>(Native.Native_UWorld.GetLevels(obj.Address)); foreach (UObject level in levels) { using (TArrayUnsafe <UBlueprint> levelBlueprints = new TArrayUnsafe <UBlueprint>()) { Native.Native_ULevel.GetLevelBlueprints(level.Address, levelBlueprints.Address); foreach (UBlueprint blueprint in levelBlueprints) { UBlueprintGeneratedClass blueprintGeneratedClass = blueprint.GeneratedClass as UBlueprintGeneratedClass; if (blueprintGeneratedClass != null) { //GenerateCodeForStruct(blueprintGeneratedClass); } } } } } } } if (registeredCrashHandler) { FCoreDelegates.OnHandleSystemError.Unbind(OnAssetLoadingCrash); } assetCache.Save(); EndGenerateModule(module); EndGenerateModules(); }
private void AppendAttribute(CSharpTextBuilder builder, UField field, UnrealModuleInfo module, bool isCollapsedMember) { UnrealModuleType moduleType; UnrealModuleType moduleAssetType; string moduleName = GetModuleName(field, out moduleType, out moduleAssetType); if (string.IsNullOrEmpty(moduleName)) { moduleName = module.Name; } List <string> attributes = new List <string>(); // TODO: Combine all of this into EPropertyType (add some TypeCode into UField?) bool isInterface = false; UEnum unrealEnum = field as UEnum; UClass unrealClass = field as UClass; UScriptStruct unrealStruct = field as UScriptStruct; UFunction unrealFunction = field as UFunction; if (unrealFunction != null) { if (unrealFunction.HasAnyFunctionFlags(EFunctionFlags.Delegate)) { attributes.Add("UDelegate"); } else { string additionalFunctionInfo = string.Empty; // TODO: Only get the script name for virtual functions / interface functions as we currently only need // this for finding the base function for hooking things up to the native base types. string scriptFunctionName; if (unrealFunction.GetScriptName(out scriptFunctionName)) { additionalFunctionInfo += ", OriginalName=\"" + unrealFunction.GetName() + "\""; } if (isCollapsedMember) { // The Flags here might not contain too useful information if there is both a get/set function. // Maybe include a second flags var? attributes.Add("UFunctionAsProp(Flags=0x" + ((uint)unrealFunction.FunctionFlags).ToString("X8") + additionalFunctionInfo + ")"); } else { attributes.Add("UFunction(Flags=0x" + ((uint)unrealFunction.FunctionFlags).ToString("X8") + additionalFunctionInfo + ")"); } } } UProperty unrealProperty = field as UProperty; if (unrealProperty != null) { attributes.Add("UProperty(Flags=(PropFlags)0x" + ((ulong)unrealProperty.PropertyFlags).ToString("X16") + ")"); } if (unrealStruct != null) { attributes.Add("UStruct(Flags=0x" + ((uint)unrealStruct.StructFlags).ToString("X8") + ")"); } else if (unrealClass != null) { // Abstract isn't really required but might help with code browsing to know what is abstract // and what isn't. Therefore put it at the start of the attributes list. if (unrealClass.HasAnyClassFlags(EClassFlags.Abstract)) { attributes.Add("Abstract"); } isInterface = unrealClass.IsChildOf <UInterface>(); if (isInterface) { attributes.Add("UInterface(Flags=0x" + ((uint)unrealClass.ClassFlags).ToString("X8") + ")"); } else { attributes.Add("UClass(Flags=(ClassFlags)0x" + ((uint)unrealClass.ClassFlags).ToString("X8") + ")"); } } if (unrealEnum != null) { attributes.Add("UEnum"); } if (unrealEnum != null || unrealClass != null || unrealStruct != null) { bool blueprintType = false; bool blueprintable = false; if (unrealEnum != null) { blueprintType = field.GetBoolMetaData(MDClass.BlueprintType); } else { GetBlueprintability(field as UStruct, out blueprintType, out blueprintable); } if (blueprintType) { attributes.Add(UMeta.GetKey(MDClass.BlueprintType)); } if (unrealClass != null && blueprintable) { attributes.Add(UMeta.GetKey(MDClass.Blueprintable)); } attributes.Add("UMetaPath(\"" + field.GetPathName() + "\"" + (isInterface ? ", InterfaceImpl=typeof(" + GetTypeName(unrealClass, null) + "Impl" + ")" : string.Empty) + ")"); } else { attributes.Add("UMetaPath(\"" + field.GetPathName() + "\")"); } if (attributes.Count > 0) { builder.AppendLine("[" + string.Join(", ", attributes) + "]"); } }
private void AppendAttribute(CSharpTextBuilder builder, UField field, UnrealModuleInfo module, bool isCollapsedMember) { UnrealModuleType moduleType; UnrealModuleType moduleAssetType; string moduleName = GetModuleName(field, out moduleType, out moduleAssetType); if (string.IsNullOrEmpty(moduleName)) { moduleName = module.Name; } List <string> attributes = new List <string>(); // TODO: Combine all of this into EPropertyType (add some TypeCode into UField?) bool isInterface = false; UEnum unrealEnum = field as UEnum; UClass unrealClass = field as UClass; UScriptStruct unrealStruct = field as UScriptStruct; UFunction unrealFunction = field as UFunction; if (unrealFunction != null) { if (unrealFunction.HasAnyFunctionFlags(EFunctionFlags.Delegate)) { attributes.Add("UDelegate"); } else { if (isCollapsedMember) { // The Flags here might not contain too useful information if there is both a get/set function. // Maybe include a second flags var? attributes.Add("UFunctionAsProp(Flags=0x" + ((uint)unrealFunction.FunctionFlags).ToString("X8") + ")"); } else { attributes.Add("UFunction(Flags=0x" + ((uint)unrealFunction.FunctionFlags).ToString("X8") + ")"); } } } UProperty unrealProperty = field as UProperty; if (unrealProperty != null) { attributes.Add("UProperty(Flags=(PropFlags)0x" + ((ulong)unrealProperty.PropertyFlags).ToString("X16") + ")"); } if (unrealStruct != null) { attributes.Add("UStruct(Flags=0x" + ((uint)unrealStruct.StructFlags).ToString("X8") + ")"); } else if (unrealClass != null) { // Abstract isn't really required but might help with code browsing to know what is abstract // and what isn't. Therefore put it at the start of the attributes list. if (unrealClass.HasAnyClassFlags(EClassFlags.Abstract)) { attributes.Add("Abstract"); } isInterface = unrealClass.IsChildOf <UInterface>(); if (isInterface) { attributes.Add("UInterface(Flags=0x" + ((uint)unrealClass.ClassFlags).ToString("X8") + ")"); } else { // Should we skip "inherit" config name? string configNameStr = string.Empty; if (unrealClass.ClassConfigName != FName.None && !unrealClass.ClassConfigName.ToString().Equals("inherit", StringComparison.InvariantCultureIgnoreCase)) { configNameStr = ", Config=\"" + unrealClass.ClassConfigName + "\""; } attributes.Add("UClass(Flags=(ClassFlags)0x" + ((uint)unrealClass.ClassFlags).ToString("X8") + configNameStr + ")"); } } if (unrealEnum != null) { attributes.Add("UEnum"); } if (unrealEnum != null || unrealClass != null || unrealStruct != null) { bool blueprintType = false; bool blueprintable = false; if (unrealEnum != null) { blueprintType = field.GetBoolMetaData(MDClass.BlueprintType); } else { GetBlueprintability(field as UStruct, out blueprintType, out blueprintable); } if (blueprintType) { attributes.Add(UMeta.GetKey(MDClass.BlueprintType)); } if (unrealClass != null && blueprintable) { attributes.Add(UMeta.GetKey(MDClass.Blueprintable)); } if (isInterface) { } attributes.Add("UMetaPath(\"" + field.GetPathName() + "\", \"" + moduleName + "\", UnrealModuleType." + GetUnrealModuleTypeString(moduleType, moduleAssetType) + (isInterface ? ", InterfaceImpl=typeof(" + GetTypeName(unrealClass, null) + "Impl" + ")" : string.Empty) + ")"); } else { attributes.Add("UMetaPath(\"" + field.GetPathName() + "\")"); } if (attributes.Count > 0) { builder.AppendLine("[" + string.Join(", ", attributes) + "]"); } }