internal static void OnPreReloadEnd() { try { if (PreReloadEnd != null) { PreReloadEnd(); } } catch (Exception e) { FMessage.Log(ELogVerbosity.Error, "HotReload.PreReloadEnd failed. Exception: " + Environment.NewLine + e); } }
internal static void OnUnload() { Debug.Assert(FThreading.IsInGameThread(), "Load/hotreload should be on the game thread"); //if (!FThreading.IsInGameThread()) //{ // FThreading.RunUnloader(delegate { OnUnload(); }); // return; //} Data = new DataStore(); IsUnloading = true; try { if (UnloadBegin != null) { UnloadBegin(); } } catch (Exception e) { FMessage.Log(ELogVerbosity.Error, "HotReload.UnloadBegin failed. Exception: " + Environment.NewLine + e); } Engine.FUSharpLatentAction.OnUnload(); Engine.ManagedLatentCallbackHelper.UnregisterCallbacks(); StaticVarManager.OnUnload(); EngineLoop.OnUnload(); FThreading.OnUnload(); FTicker.OnUnload(); IConsoleManager.OnUnload(); ManagedUnrealTypes.OnUnload(); GCHelper.OnUnload(); UnbindNativeDelegates(); IsUnloaded = true; try { if (UnloadEnd != null) { UnloadEnd(); } } catch (Exception e) { FMessage.Log(ELogVerbosity.Error, "HotReload.UnloadEnd failed. Exception: " + Environment.NewLine + e); } }
private void UpdateNativeRegistrar() { if (registerNativeDelegate != null) { return; } BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public; FieldInfo[] fields = typeof(TRegisterNativeDelegate).DeclaringType.GetFields(bindingFlags); foreach (FieldInfo field in fields) { if (field.IsStatic && field.FieldType == typeof(TRegisterNativeDelegate)) { registerNativeDelegate = field.GetValue(null) as TRegisterNativeDelegate; if (registerNativeDelegate != null) { Delegate del = registerNativeDelegate as Delegate; // Mono / .NET Framework have slightly different requirements for what we are doing with CreateDelegate // - Mono requires firstArg to be null to create a valid delegate // - NET Framework requires the del as context otherwise when the delegate is called an exception is thrown object firstArg = null; if (!AssemblyContext.IsMono) { firstArg = del; } if (IsMulticast) { registerNativeMulticastDelegateWrapper = (RegisterNativeMulticastDelegateWrapper) Delegate.CreateDelegate(typeof(RegisterNativeMulticastDelegateWrapper), firstArg, del.Method); } else { registerNativeDelegateWrapper = (RegisterNativeDelegateWrapper) Delegate.CreateDelegate(typeof(RegisterNativeDelegateWrapper), firstArg, del.Method); } } else { FMessage.Log(ELogVerbosity.Error, "Failed to find native delegate '" + typeof(TRegisterNativeDelegate).FullName + "'. Did you call REGISTER_FUNC()?"); } break; } } }
private static void SetMinimalHotReload(string[] args) { bool value; if (args != null && args.Length >= 1 && bool.TryParse(args[0], out value)) { } else { value = !Native_SharpHotReloadUtils.Get_MinimalHotReload(); } Native_SharpHotReloadUtils.Set_MinimalHotReload(value); FMessage.Log("USharpMinHotReload: " + (value ? "Enabled" : "Disabled")); }
private static void ValidateStructSize <T>(Native_SizeOfStruct.Del_SizeOf func) where T : struct { if (func != null) { int managedSize = Marshal.SizeOf <T>(); int nativeSize = func(); if (managedSize != nativeSize) { string error = string.Format("Struct size mismatch on '{0}' managed:{1} native:{2}", typeof(T), managedSize, nativeSize); FMessage.Log(ELogVerbosity.Error, error); System.Diagnostics.Debug.WriteLine(error); System.Diagnostics.Debug.Assert(false, error); } } }
private static void OnRemove(IntPtr gcHandlePtr) { GCHandle gcHandle = GCHandle.FromIntPtr(gcHandlePtr); UObjectRef objRef = (UObjectRef)gcHandle.Target; FMessage.Log("GC " + (objRef.Managed == null ? "null" : objRef.Managed.GetType().ToString()) + " (" + gcHandlePtr.ToString("X16") + ")"); objRef.Managed.ReleaseInjectedInterfaces(); objRef.Managed.objRef = null; // This will make UObject.IsDestroyed true objRef.Managed.Address = IntPtr.Zero; // Reset the address References.Remove(objRef.Native); gcHandle.Free(); // Return the objRef to the pool (this will also reset the objRef state back to empty) objRefPool.ReturnObject(objRef); }
private static int offset_bArrayContextFailed; //bool internal static void OnNativeFunctionsRegistered() { int offset = (int)Native_FFrame.GetNodeOffset(); int endOffset = (int)Native_FFrame.GetbArrayContextFailedOffset(); offset_Node = offset; offset += IntPtr.Size; offset_Object = offset; offset += IntPtr.Size; offset_Code = offset; offset += IntPtr.Size; offset_Locals = offset; offset += IntPtr.Size; offset_MostRecentProperty = offset; offset += IntPtr.Size; offset_MostRecentPropertyAddress = offset; offset += IntPtr.Size; offset_FlowStack = offset; offset += (int)Native_FFrame.GetFlowStackSize(); offset_PreviousFrame = offset; offset += IntPtr.Size; offset_OutParms = offset; offset += IntPtr.Size; offset_PropertyChainForCompiledIn = offset; offset += IntPtr.Size; offset_CurrentNativeFunction = offset; offset += IntPtr.Size; offset_bArrayContextFailed = offset; if (offset != endOffset) { string error = string.Format("Failed calculate offsets for FFrame. Expected:{0} actual:{1}", offset, endOffset); FMessage.Log(ELogVerbosity.Error, error); System.Diagnostics.Debug.WriteLine(error); System.Diagnostics.Debug.Assert(false, error); } }
private static void ValidateStructSize <T>(Native_SizeOfStruct.Del_SizeOf func, int managedSize) where T : struct { int nativeSize = func(); if (managedSize != nativeSize) { string error = string.Format("Struct size mismatch on '{0}' managed:{1} native:{2}", typeof(T), managedSize, nativeSize); FMessage.Log(ELogVerbosity.Error, error); #if DEBUG System.Diagnostics.Debug.WriteLine(error); System.Diagnostics.Debug.Assert(false, error); #else FMessage.OpenDialog(error); #endif } }
private IntPtr FindProperty(string propertyName) { FName fname = new FName(propertyName); IntPtr property = Native_UStruct.FindPropertyByName(nativeClass, ref fname); if (!(FBuild.BuildShipping || FBuild.BuildTest)) { if (property == IntPtr.Zero) { FMessage.Log(FMessage.LogNet, ELogVerbosity.Fatal, $"Attempt to replicate property '{propertyName}' which does not exist."); } else if (!Native_UProperty.HasAnyPropertyFlags(property, EPropertyFlags.Net)) { FMessage.Log(FMessage.LogNet, ELogVerbosity.Fatal, $"Attempt to replicate property '{propertyName}' that was not tagged to replicate! Please use 'Replicated' or 'ReplicatedUsing' keyword in the UProperty() declaration."); } } return(property); }
/// <summary> /// This will check for conflicts when finding interface functions. If there is a conflict /// the code output is likely to be undesirable. /// </summary> private void ValidateNoInterfaceFunctionConflict(UClass unrealClass, UFunction function, UClass skipInterface, bool skipSelf) { FName functionName = function.GetFName(); UFunction conflictFunction = null; foreach (FImplementedInterface implementedInterface in unrealClass.Interfaces) { UClass interfaceClass = implementedInterface.InterfaceClass; if (interfaceClass != null && interfaceClass != skipInterface) { if ((conflictFunction = interfaceClass.FindFunctionByName(functionName, true)) != null) { break; } } } if (conflictFunction == null && !skipSelf) { conflictFunction = unrealClass.FindFunctionByName(functionName, false); } if (conflictFunction == null) { UClass parentClass = unrealClass.GetSuperClass(); if (parentClass != null) { // Search the rest of the hierarchy conflictFunction = parentClass.FindFunctionByName(functionName, true); } } if (conflictFunction != null) { string warning = "Function redefined in hierarchy where interfaces are used. This is likely going to produce " + "unexpected results and should be avoided where possible. ImplementedInClass: '" + unrealClass.GetPathName() + "' InterfaceFunc: '" + function.GetPathName() + "' ConflictFunc: '" + conflictFunction.GetPathName() + "'"; FMessage.Log(ELogVerbosity.Warning, warning, "USharp-CodeGenerator"); } }
public void GenerateCodeForModule(string moduleName, bool loadModule) { string longPackageName = FPackageName.ConvertToLongScriptPackageName(moduleName); UPackage package = UObject.FindObjectFast <UPackage>(null, new FName(longPackageName), false, false); if (package == null && !FModuleManager.Instance.IsModuleLoaded(new FName(moduleName))) { // package is almost always non-null even when IsModuleLoaded returns false - if the package is non-null it // seems the module types are available so we don't have to call LoadModule (check if this is always true) if (!loadModule) { return; } EModuleLoadResult loadResult; FModuleManager.Instance.LoadModuleWithFailureReason(new FName(moduleName), out loadResult); if (loadResult != EModuleLoadResult.Success) { FMessage.Log("Failed to load module '" + moduleName + "'. Reason: " + loadResult); return; } package = UObject.FindObjectFast <UPackage>(null, new FName(longPackageName), false, false); } if (package != null) { Dictionary <FName, string> modulePaths = FModulesPaths.FindModulePaths("*"); string modulePath; if (!modulePaths.TryGetValue(new FName(moduleName), out modulePath)) { return; } BeginGenerateModules(); GenerateCodeForModule(new UnrealModuleInfo(package, moduleName, modulePath)); EndGenerateModules(); } }
private void UpdateNativeRegistrar() { if (registerNativeDelegate != null) { return; } BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public; FieldInfo[] fields = typeof(TRegisterNativeDelegate).DeclaringType.GetFields(bindingFlags); foreach (FieldInfo field in fields) { if (field.IsStatic && field.FieldType == typeof(TRegisterNativeDelegate)) { registerNativeDelegate = field.GetValue(null) as TRegisterNativeDelegate; if (registerNativeDelegate != null) { Delegate del = registerNativeDelegate as Delegate; if (IsMulticast) { registerNativeMulticastDelegateWrapper = (RegisterNativeMulticastDelegateWrapper) Delegate.CreateDelegate(typeof(RegisterNativeMulticastDelegateWrapper), del, del.Method); } else { registerNativeDelegateWrapper = (RegisterNativeDelegateWrapper) Delegate.CreateDelegate(typeof(RegisterNativeDelegateWrapper), del, del.Method); } } else { FMessage.Log(ELogVerbosity.Error, "Failed to find native delegate '" + typeof(TRegisterNativeDelegate).FullName + "'. Did you call REGISTER_FUNC()?"); } break; } } }
public void Add <T>(T value) where T : DataItem { string typeName = typeof(T).AssemblyQualifiedName; if (string.IsNullOrEmpty(typeName)) { return; } try { DataItem.Info info = new DataItem.Info(); info.Data = value; value.info = info; value.DataStore = this; values.Add(typeName, info); } catch (ArgumentException) { FMessage.Log(ELogVerbosity.Error, "HotReload item with the same type has already been added. Type: " + typeof(T).FullName); } }
private static void OnPostGarbageCollect() { FMessage.Log("OnPostGarbageCollectBegin"); Native_GCHelper.CollectGarbage(); FMessage.Log("OnPostGarbageCollectEnd"); }
private static unsafe IntPtr OnAdd(IntPtr native) { UObjectRef objRef = null; int objectInternalIndex = *(int *)(native + objectInternalIndexOffset); #if ARRAY_GC while (References.Count <= objectInternalIndex) { References.Add(null); } if (References[objectInternalIndex] == null) #else if (!References.TryGetValue(native, out objRef)) #endif { bool isKnownType; Type type = UClass.GetFirstKnownType(native, out isKnownType, false); if (type == null) { // This probably means the given address is not valid (check IsValid/IsValidLowLevel/IsValidLowLevelFast ?) string className = string.Empty; string fullName = string.Empty; try { using (FStringUnsafe classNameUnsafe = new FStringUnsafe()) { Native_UObjectBaseUtility.GetName(Native_UObjectBase.GetClass(native), ref classNameUnsafe.Array); className = classNameUnsafe.Value; } } catch { } try { using (FStringUnsafe fullNameUnsafe = new FStringUnsafe()) { Native_UObjectBaseUtility.GetFullName(native, IntPtr.Zero, ref fullNameUnsafe.Array); fullName = fullNameUnsafe.Value; } } catch { } // Get a smaller stack snippet StackTrace stack = null; try { stack = new StackTrace(4); } catch { } string error = string.Format("[GCHelper-Error] Couldn't find type for requested UObject. Address: {0} (0x{1}) Name: \"{2}\" FullName: \"{3}\" Stack:\r\n{4}", native.ToInt32(), native.ToInt32().ToString("X8"), className, fullName, stack); FMessage.Log(ELogVerbosity.Error, error); Debug.Assert(false, error); return(IntPtr.Zero); } if (type.IsInterface) { // Validate that we are getting a UInterface and we aren't doing something very wrong. Debug.Assert(Native_UObjectBaseUtility.IsA(native, UClass.GetClassAddress(type))); // This should be a UInterface instance. We might want to do something more complex here // where interfaces inherit from other interfaces. type = typeof(UInterface); } objRef = objRefPool.New(native, type, isKnownType, objectInternalIndex); #if ARRAY_GC References[objectInternalIndex] = objRef; #else References.Add(native, objRef); #endif return(GCHandle.ToIntPtr(objRef.ManagedHandle)); } return(GCHandle.ToIntPtr(objRef.ManagedHandle)); }
protected void Log(ELogVerbosity verbosity, string value, params object[] args) { FMessage.Log(LogCategory, verbosity, string.Format(value, args)); }
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 static void GenerateCode(bool timeSliced, string[] args) { try { bool invalidArgs = false; if (args.Length > 0) { if (args[0] == "cancel") { if (timeSlicedCodeGenerator != null && !timeSlicedCodeGenerator.Complete) { timeSlicedCodeGenerator.EndGenerateModules(); } timeSlicedCodeGenerator = null; return; } if (timeSlicedCodeGenerator != null) { FMessage.Log("Already generating code"); return; } CodeGenerator codeGenerator = null; switch (args[0]) { case "game": 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 "engine": loadMode = CodeGenerator.AssetLoadMode.Engine; 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(timeSliced); codeGenerator.GenerateCodeForGame(loadMode, clearAssetCache, skipLevels); break; case "gameplugins": codeGenerator = new CodeGenerator(timeSliced); codeGenerator.GenerateCodeForModules(new UnrealModuleType[] { UnrealModuleType.GamePlugin }); break; case "modules": codeGenerator = new CodeGenerator(timeSliced); //codeGenerator.Settings.ExportMode = CodeGeneratorSettings.CodeExportMode.All; //codeGenerator.Settings.ExportAllFunctions = true; //codeGenerator.Settings.ExportAllProperties = true; codeGenerator.GenerateCodeForAllModules(); break; case "module": if (args.Length > 1) { codeGenerator = new CodeGenerator(timeSliced); // Tests / using these for types for use in this lib //codeGenerator.Settings.CheckUObjectDestroyed = false; //codeGenerator.Settings.GenerateIsValidSafeguards = false; //codeGenerator.Settings.ExportMode = CodeGeneratorSettings.CodeExportMode.All; //codeGenerator.Settings.ExportAllFunctions = true; //codeGenerator.Settings.ExportAllProperties = true; //codeGenerator.Settings.MergeEnumFiles = false; codeGenerator.GenerateCodeForModule(args[1], true); } else { invalidArgs = true; } break; case "compile": CompileGeneratedCode(); break; default: invalidArgs = true; break; } if (!invalidArgs && timeSliced && codeGenerator != null) { timeSlicedCodeGenerator = codeGenerator; Coroutine.StartCoroutine(null, ProcessTimeSlice()); } } 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 string GetFunctionSignature(UnrealModuleInfo module, UFunction function, UStruct owner, string customFunctionName, string customModifiers, bool stripAdditionalText, bool isImplementationMethod, List <string> namespaces) { bool isInterface = owner != null && owner.IsChildOf <UInterface>(); bool isDelegate = function.HasAnyFunctionFlags(EFunctionFlags.Delegate | EFunctionFlags.MulticastDelegate); bool isStatic = function.HasAnyFunctionFlags(EFunctionFlags.Static); bool isBlueprintType = owner != null && owner.IsA <UBlueprintGeneratedClass>(); StringBuilder modifiers = new StringBuilder(); if (!string.IsNullOrEmpty(customModifiers)) { modifiers.Append(customModifiers); } else if (isInterface) { // Don't provide any modifiers for interfaces if there isn't one already provided } else { UFunction originalFunction; // NOTE: "isImplementationMethod" is talking about "_Implementation" methods. // "isInterfaceImplementation" is talking about regular methods which are implementations for a interface. bool isInterfaceImplementation; UClass originalOwner = GetOriginalFunctionOwner(function, out originalFunction, out isInterfaceImplementation); // All interface functions in the chain need to be public bool isInterfaceFunc = originalOwner != owner && originalOwner.HasAnyClassFlags(EClassFlags.Interface); if (isImplementationMethod || (function.HasAnyFunctionFlags(EFunctionFlags.Protected) && !isInterfaceFunc && !isDelegate)) { modifiers.Append("protected"); } else { modifiers.Append("public"); } if (isDelegate) { modifiers.Append(" delegate"); } if (isStatic) { modifiers.Append(" static"); } if (!isDelegate && !isStatic) { if (function.HasAnyFunctionFlags(EFunctionFlags.BlueprintEvent)) { UFunction superFunc = function.GetSuperFunction(); if (superFunc != null) { modifiers.Append(" override"); } else { // This have should been filtered out in CanExportFunction() Debug.Assert(originalOwner == owner || isInterfaceImplementation); // Explicit will have the _Implementation as virtual and the function declaration as // non-virtual (which is the same as C++) if (!Settings.UseExplicitImplementationMethods || isImplementationMethod) { modifiers.Append(" virtual"); } } } else { if (originalOwner != owner && !isInterfaceFunc) { // Add "new" if the parent class has a function with the same name but not BlueprintEvent. // (don't do this for interface functions as we are implementing the function not redefining it) modifiers.Append(" new"); } } } } string returnType = "void"; int numReturns = 0; StringBuilder parameters = new StringBuilder(); // index is the index into parameters string Dictionary <int, string> parameterDefaultsByIndex = new Dictionary <int, string>(); // Once this is true all parameters from that point should also have defaults bool hasDefaultParameters = false; // Blueprint can define ref/out parameters with default values, this can't be translated to code bool invalidDefaultParams = false; // Info so we can avoid param name conflicts Dictionary <UProperty, string> paramNames = GetParamNames(function); // Generic array parameters string[] arrayParamNames = function.GetCommaSeperatedMetaData("ArrayParam"); // Generic parameters depending on array type string[] arrayTypeDependentParamNames = function.GetCommaSeperatedMetaData("ArrayTypeDependentParams"); // AutoCreateRefTerm will force ref on given parameter names (comma seperated) string[] autoRefParamNames = function.GetCommaSeperatedMetaData("AutoCreateRefTerm"); // If this is a blueprint type try and getting the return value from the first out param (if there is only one out) UProperty blueprintReturnProperty = function.GetBlueprintReturnProperty(); bool firstParameter = true; foreach (KeyValuePair <UProperty, string> param in paramNames) { UProperty parameter = param.Key; string paramName = param.Value; string rawParamName = parameter.GetName(); if (!parameter.HasAnyPropertyFlags(EPropertyFlags.Parm)) { continue; } if (parameter.HasAnyPropertyFlags(EPropertyFlags.ReturnParm) || parameter == blueprintReturnProperty) { returnType = GetTypeName(parameter, namespaces); numReturns++; } else { if (firstParameter) { firstParameter = false; } else { parameters.Append(", "); } if (!parameter.HasAnyPropertyFlags(EPropertyFlags.ConstParm)) { if (parameter.HasAnyPropertyFlags(EPropertyFlags.ReferenceParm) || autoRefParamNames.Contains(rawParamName)) { parameters.Append("ref "); } else if (parameter.HasAnyPropertyFlags(EPropertyFlags.OutParm)) { parameters.Append("out "); } } string paramTypeName = GetTypeName(parameter, namespaces); if (arrayParamNames.Contains(rawParamName)) { int genericsIndex = paramTypeName.IndexOf('<'); if (genericsIndex >= 0) { paramTypeName = paramTypeName.Substring(0, genericsIndex) + "<T>"; } } else if (arrayTypeDependentParamNames.Contains(rawParamName)) { paramTypeName = "T"; } parameters.Append(paramTypeName + " " + paramName); if (!invalidDefaultParams) { string defaultValue = GetParamDefaultValue(function, parameter, paramTypeName, ref hasDefaultParameters, ref invalidDefaultParams); if (!string.IsNullOrEmpty(defaultValue) && !invalidDefaultParams) { if (isBlueprintType && (parameter.HasAnyPropertyFlags(EPropertyFlags.ReferenceParm | EPropertyFlags.OutParm) || autoRefParamNames.Contains(rawParamName))) { invalidDefaultParams = true; } else { if (!hasDefaultParameters) { hasDefaultParameters = true; } parameterDefaultsByIndex[parameters.Length] = " = " + defaultValue; } } } } } if (numReturns > 1) { FMessage.Log(ELogVerbosity.Error, "More than 1 return on function '" + function.GetPathName() + "'"); } // Insert the default parameters if they aren't invalid if (!invalidDefaultParams) { int offset = 0; foreach (KeyValuePair <int, string> parameterDefault in parameterDefaultsByIndex) { parameters.Insert(parameterDefault.Key + offset, parameterDefault.Value); offset += parameterDefault.Value.Length; } } string functionName = GetFunctionName(function); string additionalStr = string.Empty; if (isDelegate) { functionName = GetTypeNameDelegate(function); additionalStr = ";"; } //if (isInterface) //{ // additionalStr = ";"; //} if (isImplementationMethod) { functionName += Settings.VarNames.ImplementationMethod; } if (!string.IsNullOrEmpty(customFunctionName)) { functionName = customFunctionName; } if (stripAdditionalText) { additionalStr = string.Empty; } string generics = string.Empty; if (arrayParamNames.Length > 0 || arrayTypeDependentParamNames.Length > 0) { generics = "<T>"; } if (modifiers.Length > 0) { modifiers.Append(' '); } return(string.Format("{0}{1} {2}{3}({4}){5}", modifiers, returnType, functionName, generics, parameters, additionalStr)); }
private void ProcessCommon(EExprToken opcode) { switch (opcode) { case EExprToken.EX_PrimitiveCast: { // A type conversion. byte conversionType = ReadByte(); output.AppendLine(FmtOpcodeIndent(opcode) + "PrimitiveCast of type " + conversionType); AddIndent(); output.AppendLine(indents + " Argument:"); ProcessCastByte(conversionType); //@TODO: //Ar.Logf(TEXT("%s Expression:"), *Indents); //SerializeExpr( ScriptIndex ); break; } case EExprToken.EX_SetSet: { output.AppendLine(FmtOpcodeIndent(opcode) + "set set"); SerializeExpr(); ReadInt32(); while (SerializeExpr() != EExprToken.EX_EndSet) { // Set contents } break; } case EExprToken.EX_EndSet: { output.AppendLine(FmtOpcodeIndent(opcode) + "EX_EndSet"); break; } case EExprToken.EX_SetConst: { UProperty innerProp = ReadPointer <UProperty>(); int num = ReadInt32(); output.AppendLine(FmtOpcodeIndent(opcode) + "set set const - elements number: " + num + ", inner property: " + UObject.GetNameSafe(innerProp)); while (SerializeExpr() != EExprToken.EX_EndSetConst) { // Set contents } break; } case EExprToken.EX_EndSetConst: { output.AppendLine(FmtOpcodeIndent(opcode) + "EX_EndSetConst"); break; } case EExprToken.EX_SetMap: { output.AppendLine(FmtOpcodeIndent(opcode) + "set map"); SerializeExpr(); ReadInt32(); while (SerializeExpr() != EExprToken.EX_EndMap) { // Map contents } break; } case EExprToken.EX_EndMap: { output.AppendLine(FmtOpcodeIndent(opcode) + "EX_EndMap"); break; } case EExprToken.EX_MapConst: { UProperty keyProp = ReadPointer <UProperty>(); UProperty valProp = ReadPointer <UProperty>(); int num = ReadInt32(); output.AppendLine(FmtOpcodeIndent(opcode) + "set map const - elements number: " + num + ", key property: " + UObject.GetNameSafe(keyProp) + ", val property: " + UObject.GetNameSafe(valProp)); while (SerializeExpr() != EExprToken.EX_EndMapConst) { // Map contents } break; } case EExprToken.EX_ObjToInterfaceCast: { // A conversion from an object variable to a native interface variable. // We use a different bytecode to avoid the branching each time we process a cast token // the interface class to convert to UClass interfaceClass = ReadPointer <UClass>(); output.AppendLine(FmtOpcodeIndent(opcode) + "ObjToInterfaceCast to " + interfaceClass.GetName()); SerializeExpr(); break; } case EExprToken.EX_CrossInterfaceCast: { // A conversion from one interface variable to a different interface variable. // We use a different bytecode to avoid the branching each time we process a cast token // the interface class to convert to UClass interfaceClass = ReadPointer <UClass>(); output.AppendLine(FmtOpcodeIndent(opcode) + "InterfaceToInterfaceCast to " + interfaceClass.GetName()); SerializeExpr(); break; } case EExprToken.EX_InterfaceToObjCast: { // A conversion from an interface variable to a object variable. // We use a different bytecode to avoid the branching each time we process a cast token // the interface class to convert to UClass objectClass = ReadPointer <UClass>(); output.AppendLine(FmtOpcodeIndent(opcode) + "InterfaceToObjCast to " + objectClass.GetName()); SerializeExpr(); break; } case EExprToken.EX_Let: { output.AppendLine(FmtOpcodeIndent(opcode) + "Let (Variable = Expression)"); AddIndent(); ReadPointer <UProperty>(); // Variable expr. output.AppendLine(indents + " Variable:"); SerializeExpr(); // Assignment expr. output.AppendLine(indents + " Expression:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_LetObj: case EExprToken.EX_LetWeakObjPtr: { if (opcode == EExprToken.EX_LetObj) { output.AppendLine(FmtOpcodeIndent(opcode) + "Let Obj (Variable = Expression)"); } else { output.AppendLine(FmtOpcodeIndent(opcode) + "Let WeakObjPtr (Variable = Expression)"); } AddIndent(); // Variable expr. output.AppendLine(indents + " Variable:"); SerializeExpr(); // Assignment expr. output.AppendLine(indents + " Expression:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_LetBool: { output.AppendLine(FmtOpcodeIndent(opcode) + "LetBool (Variable = Expression)"); AddIndent(); // Variable expr. output.AppendLine(indents + " Variable:"); SerializeExpr(); // Assignment expr. output.AppendLine(indents + " Expression:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_LetValueOnPersistentFrame: { output.AppendLine(FmtOpcodeIndent(opcode) + "LetValueOnPersistentFrame"); AddIndent(); UProperty prop = ReadPointer <UProperty>(); output.AppendLine(indents + " Destination variable: " + UObject.GetNameSafe(prop) + ", offset: " + (prop != null ? prop.GetOffset_ForDebug() : 0)); output.AppendLine(indents + " Expression:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_StructMemberContext: { output.AppendLine(FmtOpcodeIndent(opcode) + "Struct member context"); AddIndent(); UProperty prop = ReadPointer <UProperty>(); // although that isn't a UFunction, we are not going to indirect the props of a struct, so this should be fine output.AppendLine(indents + " Expression within struct " + prop.GetName() + ", offset " + prop.GetOffset_ForDebug()); output.AppendLine(indents + " Expression to struct:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_LetDelegate: { output.AppendLine(FmtOpcodeIndent(opcode) + "LetDelegate (Variable = Expression)"); AddIndent(); // Variable expr. output.AppendLine(indents + " Variable:"); SerializeExpr(); // Assignment expr. output.AppendLine(indents + " Expression:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_LetMulticastDelegate: { output.AppendLine(FmtOpcodeIndent(opcode) + "LetMulticastDelegate (Variable = Expression)"); AddIndent(); // Variable expr. output.AppendLine(indents + " Variable:"); SerializeExpr(); // Assignment expr. output.AppendLine(indents + " Expression:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_ComputedJump: { output.AppendLine(FmtOpcodeIndent(opcode) + "Computed Jump, offset specified by expression:"); AddIndent(); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_Jump: { uint skipCount = ReadSkipCount(); output.AppendLine(FmtOpcodeIndent(opcode) + "Jump to offset " + FmtSkipCount(skipCount)); break; } case EExprToken.EX_LocalVariable: { UProperty property = ReadPointer <UProperty>(); output.AppendLine(FmtOpcodeIndent(opcode) + "Local variable named " + FmtObjNameOrNull(property)); break; } case EExprToken.EX_DefaultVariable: { UProperty property = ReadPointer <UProperty>(); output.AppendLine(FmtOpcodeIndent(opcode) + "Default variable named " + FmtObjNameOrNull(property)); break; } case EExprToken.EX_InstanceVariable: { UProperty property = ReadPointer <UProperty>(); output.AppendLine(FmtOpcodeIndent(opcode) + "Instance variable named " + FmtObjNameOrNull(property)); break; } case EExprToken.EX_LocalOutVariable: { UProperty property = ReadPointer <UProperty>(); output.AppendLine(FmtOpcodeIndent(opcode) + "Local out variable named " + FmtObjNameOrNull(property)); break; } case EExprToken.EX_InterfaceContext: { output.AppendLine(FmtOpcodeIndent(opcode) + "EX_InterfaceContext:"); SerializeExpr(); break; } case EExprToken.EX_DeprecatedOp4A: { output.AppendLine(FmtOpcodeIndent(opcode) + "This opcode has been removed and does nothing."); break; } case EExprToken.EX_Nothing: case EExprToken.EX_EndOfScript: case EExprToken.EX_EndFunctionParms: case EExprToken.EX_EndStructConst: case EExprToken.EX_EndArray: case EExprToken.EX_EndArrayConst: case EExprToken.EX_IntZero: case EExprToken.EX_IntOne: case EExprToken.EX_True: case EExprToken.EX_False: case EExprToken.EX_NoObject: case EExprToken.EX_NoInterface: case EExprToken.EX_Self: case EExprToken.EX_EndParmValue: { output.AppendLine(FmtOpcodeIndent(opcode) + opcode.ToString()); break; } case EExprToken.EX_Return: { output.AppendLine(FmtOpcodeIndent(opcode) + opcode.ToString()); SerializeExpr(); // Return expression. break; } case EExprToken.EX_CallMath: { UStruct stackNode = ReadPointer <UStruct>(); output.AppendLine(FmtOpcodeIndent(opcode) + "Call Math (stack node " + UObject.GetNameSafe(stackNode != null ? stackNode.GetOuter() : null) + "::" + UObject.GetNameSafe(stackNode) + ")"); while (SerializeExpr() != EExprToken.EX_EndFunctionParms) { // Params } break; } case EExprToken.EX_FinalFunction: { UStruct stackNode = ReadPointer <UStruct>(); output.AppendLine(FmtOpcodeIndent(opcode) + "Final Function (stack node " + FmtObjOuterNameOrNull(stackNode) + "::" + FmtObjNameOrNull(stackNode) + ")"); while (SerializeExpr() != EExprToken.EX_EndFunctionParms) { // Params } break; } case EExprToken.EX_CallMulticastDelegate: { UStruct stackNode = ReadPointer <UStruct>(); output.AppendLine(FmtOpcodeIndent(opcode) + "CallMulticastDelegate (signature " + FmtObjOuterNameOrNull(stackNode) + "::" + FmtObjNameOrNull(stackNode) + ") delegate:"); SerializeExpr(); output.AppendLine(FmtOpcodeIndent(opcode) + "Params:"); while (SerializeExpr() != EExprToken.EX_EndFunctionParms) { // Params } break; } case EExprToken.EX_VirtualFunction: { string functionName = ReadName(); output.AppendLine(FmtOpcodeIndent(opcode) + "Virtual Function named " + functionName); while (SerializeExpr() != EExprToken.EX_EndFunctionParms) { } break; } case EExprToken.EX_ClassContext: case EExprToken.EX_Context: case EExprToken.EX_Context_FailSilent: { output.AppendLine(FmtOpcodeIndent(opcode) + (opcode == EExprToken.EX_ClassContext ? "Class Context" : "Context")); AddIndent(); // Object expression. output.AppendLine(indents + " ObjectExpression:"); SerializeExpr(); if (opcode == EExprToken.EX_Context_FailSilent) { output.AppendLine(indents + " Can fail silently on access none "); } // Code offset for NULL expressions. uint skipCount = ReadSkipCount(); output.AppendLine(indents + " Skip Bytes: " + FmtSkipCount(skipCount)); // Property corresponding to the r-value data, in case the l-value needs to be mem-zero'd UField field = ReadPointer <UField>(); output.AppendLine(indents + " R-Value Property: " + FmtObjNameOrNull(field)); // Context expression. output.AppendLine(indents + " ContextExpression:"); SerializeExpr(); DropIndent(); break; } case EExprToken.EX_IntConst: { int constValue = ReadInt32(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal int32 " + constValue); break; } case EExprToken.EX_SkipOffsetConst: { uint constValue = ReadSkipCount(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal CodeSkipSizeType " + FmtSkipCount(constValue)); break; } case EExprToken.EX_FloatConst: { float constValue = ReadFloat(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal float " + constValue); break; } case EExprToken.EX_StringConst: { string constValue = ReadString8(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal ansi string \"" + constValue + "\""); break; } case EExprToken.EX_UnicodeStringConst: { string constValue = ReadString16(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal unicode string \"" + constValue + "\""); break; } case EExprToken.EX_TextConst: { // What kind of text are we dealing with? EBlueprintTextLiteralType textLiteralType = (EBlueprintTextLiteralType)script[scriptIndex++]; switch (textLiteralType) { case EBlueprintTextLiteralType.Empty: { output.AppendLine(FmtOpcodeIndent(opcode) + "literal text - empty"); break; } case EBlueprintTextLiteralType.LocalizedText: { string sourceString = ReadString(); string keyString = ReadString(); string namespaceString = ReadString(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal text - localized text { namespace: \"" + namespaceString + "\", key: \"" + keyString + "\", source: \"" + sourceString + "\" }"); break; } case EBlueprintTextLiteralType.InvariantText: { string sourceString = ReadString(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal text - invariant text: \"" + sourceString + "\""); break; } case EBlueprintTextLiteralType.LiteralString: { string sourceString = ReadString(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal text - literal string: \"" + sourceString + "\""); break; } case EBlueprintTextLiteralType.StringTableEntry: { ReadPointer <UObject>(); // String Table asset (if any) string tableIdString = ReadString(); string keyString = ReadString(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal text - string table entry { tableid: \"" + tableIdString + "\", key: \"" + keyString + "\" }"); break; } default: throw new Exception("Unknown EBlueprintTextLiteralType! Please update ProcessCommon() to handle this type of text."); } break; } case EExprToken.EX_ObjectConst: { UObject pointer = ReadPointer <UObject>(); output.AppendLine(FmtOpcodeIndent(opcode) + "EX_ObjectConst (" + FmtPtr(pointer) + ":" + pointer.GetFullName()); break; } case EExprToken.EX_SoftObjectConst: { output.AppendLine(FmtOpcodeIndent(opcode) + "EX_SoftObjectConst"); SerializeExpr(); break; } case EExprToken.EX_NameConst: { string constValue = ReadName(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal name " + constValue); break; } case EExprToken.EX_RotationConst: { float pitch = ReadFloat(); float yaw = ReadFloat(); float roll = ReadFloat(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal rotation (" + pitch + "," + yaw + "," + roll + ")"); break; } case EExprToken.EX_VectorConst: { float x = ReadFloat(); float y = ReadFloat(); float z = ReadFloat(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal vector (" + x + "," + y + "," + z + ")"); break; } case EExprToken.EX_TransformConst: { float rotX = ReadFloat(); float rotY = ReadFloat(); float rotZ = ReadFloat(); float rotW = ReadFloat(); float transX = ReadFloat(); float transY = ReadFloat(); float transZ = ReadFloat(); float scaleX = ReadFloat(); float scaleY = ReadFloat(); float scaleZ = ReadFloat(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal transform " + "R(" + rotX + "," + rotY + "," + rotZ + "," + rotW + "," + ") " + "T(" + transX + "," + transY + "," + transZ + ") " + "T(" + scaleX + "," + scaleY + "," + scaleZ + ")"); break; } case EExprToken.EX_StructConst: { UScriptStruct unrealStruct = ReadPointer <UScriptStruct>(); int serializedSize = ReadInt32(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal struct " + unrealStruct.GetName() + " (serialized size: " + serializedSize + ")"); break; } case EExprToken.EX_SetArray: { output.AppendLine(FmtOpcodeIndent(opcode) + "set array"); SerializeExpr(); while (SerializeExpr() != EExprToken.EX_EndArray) { // Array contents } break; } case EExprToken.EX_ArrayConst: { UProperty innerProp = ReadPointer <UProperty>(); int num = ReadInt32(); output.AppendLine(FmtOpcodeIndent(opcode) + "set array const - elements number: " + num + ", inner property: " + UObject.GetNameSafe(innerProp)); break; } case EExprToken.EX_ByteConst: { byte constValue = ReadByte(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal byte " + constValue); break; } case EExprToken.EX_IntConstByte: { int constValue = ReadByte(); output.AppendLine(FmtOpcodeIndent(opcode) + "literal int " + constValue); break; } case EExprToken.EX_MetaCast: { UClass unrealClass = ReadPointer <UClass>(); output.AppendLine(FmtOpcodeIndent(opcode) + "MetaCast to " + unrealClass.GetName() + " of expr:"); SerializeExpr(); break; } case EExprToken.EX_DynamicCast: { UClass unrealClass = ReadPointer <UClass>(); output.AppendLine(FmtOpcodeIndent(opcode) + "DynamicCast to " + unrealClass.GetName() + " of expr:"); SerializeExpr(); break; } case EExprToken.EX_JumpIfNot: { // Code offset. uint skipCount = ReadSkipCount(); output.AppendLine(FmtOpcodeIndent(opcode) + "Jump to offset " + FmtSkipCount(skipCount) + " if not expr:"); // Boolean expr. SerializeExpr(); break; } case EExprToken.EX_Assert: { ushort lineNumber = ReadUInt16(); byte inDebugMode = ReadByte(); output.AppendLine(FmtOpcodeIndent(opcode) + "assert at line " + lineNumber + ", in debug mode = " + inDebugMode + " with expr:"); SerializeExpr(); // Assert expr. break; } case EExprToken.EX_Skip: { uint w = ReadSkipCount(); output.AppendLine(FmtOpcodeIndent(opcode) + "possibly skip " + FmtSkipCount(w) + " bytes of expr:"); // Expression to possibly skip. SerializeExpr(); break; } case EExprToken.EX_InstanceDelegate: { // the name of the function assigned to the delegate. string funcName = ReadName(); output.AppendLine(FmtOpcodeIndent(opcode) + "instance delegate function named " + funcName); break; } case EExprToken.EX_AddMulticastDelegate: { output.AppendLine(FmtOpcodeIndent(opcode) + "Add MC delegate"); SerializeExpr(); SerializeExpr(); break; } case EExprToken.EX_RemoveMulticastDelegate: { output.AppendLine(FmtOpcodeIndent(opcode) + "Remove MC delegate"); SerializeExpr(); SerializeExpr(); break; } case EExprToken.EX_ClearMulticastDelegate: { output.AppendLine(FmtOpcodeIndent(opcode) + "Clear MC delegate"); SerializeExpr(); break; } case EExprToken.EX_BindDelegate: { // the name of the function assigned to the delegate. string funcName = ReadName(); output.AppendLine(FmtOpcodeIndent(opcode) + "BindDelegate '" + funcName + "'"); output.AppendLine(indents + " Delegate:"); SerializeExpr(); output.AppendLine(indents + " Object:"); SerializeExpr(); break; } case EExprToken.EX_PushExecutionFlow: { uint skipCount = ReadSkipCount(); output.AppendLine(FmtOpcodeIndent(opcode) + "FlowStack.Push(" + FmtSkipCount(skipCount) + ");"); break; } case EExprToken.EX_PopExecutionFlow: { output.AppendLine(FmtOpcodeIndent(opcode) + "if (FlowStack.Num()) { jump to statement at FlowStack.Pop(); } else { ERROR!!! }"); break; } case EExprToken.EX_PopExecutionFlowIfNot: { output.AppendLine(FmtOpcodeIndent(opcode) + "if (!condition) { if (FlowStack.Num()) { jump to statement at FlowStack.Pop(); } else { ERROR!!! } }"); // Boolean expr. SerializeExpr(); break; } case EExprToken.EX_Breakpoint: { output.AppendLine(FmtOpcodeIndent(opcode) + "<<< BREAKPOINT >>>"); break; } case EExprToken.EX_WireTracepoint: { output.AppendLine(FmtOpcodeIndent(opcode) + ".. wire debug site .."); break; } case EExprToken.EX_InstrumentationEvent: { EScriptInstrumentation eventType = (EScriptInstrumentation)ReadByte(); switch (eventType) { case EScriptInstrumentation.InlineEvent: output.AppendLine(FmtOpcodeIndent(opcode) + ".. instrumented inline event .."); break; case EScriptInstrumentation.Stop: output.AppendLine(FmtOpcodeIndent(opcode) + ".. instrumented event stop .."); break; case EScriptInstrumentation.PureNodeEntry: output.AppendLine(FmtOpcodeIndent(opcode) + ".. instrumented pure node entry site .."); break; case EScriptInstrumentation.NodeDebugSite: output.AppendLine(FmtOpcodeIndent(opcode) + ".. instrumented debug site .."); break; case EScriptInstrumentation.NodeEntry: output.AppendLine(FmtOpcodeIndent(opcode) + ".. instrumented wire entry site .."); break; case EScriptInstrumentation.NodeExit: output.AppendLine(FmtOpcodeIndent(opcode) + ".. instrumented wire exit site .."); break; case EScriptInstrumentation.PushState: output.AppendLine(FmtOpcodeIndent(opcode) + ".. push execution state .."); break; case EScriptInstrumentation.RestoreState: output.AppendLine(FmtOpcodeIndent(opcode) + ".. restore execution state .."); break; case EScriptInstrumentation.ResetState: output.AppendLine(FmtOpcodeIndent(opcode) + ".. reset execution state .."); break; case EScriptInstrumentation.SuspendState: output.AppendLine(FmtOpcodeIndent(opcode) + ".. suspend execution state .."); break; case EScriptInstrumentation.PopState: output.AppendLine(FmtOpcodeIndent(opcode) + ".. pop execution state .."); break; case EScriptInstrumentation.TunnelEndOfThread: output.AppendLine(FmtOpcodeIndent(opcode) + ".. tunnel end of thread .."); break; } break; } case EExprToken.EX_Tracepoint: { output.AppendLine(FmtOpcodeIndent(opcode) + ".. debug site .."); break; } case EExprToken.EX_SwitchValue: { ushort numCases = ReadUInt16(); uint afterSkip = ReadSkipCount(); output.AppendLine(FmtOpcodeIndent(opcode) + "Switch Value " + numCases + " cases, end in " + FmtSkipCount(afterSkip)); AddIndent(); output.AppendLine(indents + " Index:"); SerializeExpr(); for (ushort caseIndex = 0; caseIndex < numCases; ++caseIndex) { output.AppendLine(indents + " [" + caseIndex + "] Case Index (label: " + FmtScriptIndex(scriptIndex) + ")"); SerializeExpr(); // case index value term uint offsetToNextCase = ReadSkipCount(); output.AppendLine(indents + " [" + caseIndex + "] Offset to the next case: " + FmtSkipCount(offsetToNextCase)); output.AppendLine(indents + " [" + caseIndex + "] Case Result:"); SerializeExpr(); // case term } output.AppendLine(indents + " Default result (label: " + FmtScriptIndex(scriptIndex) + ")"); SerializeExpr(); output.AppendLine(indents + " (label: " + FmtScriptIndex(scriptIndex) + ")"); DropIndent(); break; } case EExprToken.EX_ArrayGetByRef: { output.AppendLine(FmtOpcodeIndent(opcode) + "Array Get-by-Ref Index"); AddIndent(); SerializeExpr(); SerializeExpr(); DropIndent(); break; } default: { string error = "Unknown bytecode 0x" + ((byte)opcode).ToString("X2") + "; ignoring it"; output.AppendLine(FmtOpcodeIndent(opcode) + "!!!" + error); FMessage.Log(ELogVerbosity.Warning, error); } break; } }
private static void CommandLog(ELogVerbosity verbosity, string value, params object[] args) { FMessage.Log("USharp-CodeGenerator.Commands", verbosity, string.Format(value, args)); }
private static unsafe void SetDotNetRuntime(string[] args) { // It's probably possible to dynamically load runtimes by adding a function to SharedRuntimeState (and slightly modifying // the current load checks inside of CSharpLoader::Load) const string enableMoreRuntimesStr = "Only one runtime has been loaded. Modify /USharp/Binaries/Managed/Runtimes/DotNetRuntime.txt to add more runtimes and then reopen the editor."; if (args != null && args.Length > 0) { bool handled = true; switch (args[0].ToLower()) { case "diag": { // Diagnostics... FMessage.Log("============================================================================================"); FMessage.Log("Loaded modules in " + SharedRuntimeState.CurrentRuntime + ":"); foreach (System.Reflection.Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { FMessage.Log(assembly.FullName); } // Also print out the loaded AppDomain instances when under the .NET Framework (CLR) if (AssemblyContext.IsCLR) { FMessage.Log("================ Domains:"); string[] appDomains = AppDomainDiagnostic.GetNames(); if (appDomains != null) { foreach (string appDomain in appDomains) { FMessage.Log(appDomain); } } } } break; case "reload": { SharedRuntimeState.Instance->Reload = true; } break; default: handled = false; break; } if (handled) { return; } if (SharedRuntimeState.HaveMultipleRuntimesLoaded()) { EDotNetRuntime runtime = EDotNetRuntime.None; switch (args[0].ToLower()) { case "mono": runtime = EDotNetRuntime.Mono; break; case "clr": runtime = EDotNetRuntime.CLR; break; case "coreclr": runtime = EDotNetRuntime.CoreCLR; break; } if (runtime == EDotNetRuntime.None) { FMessage.Log("Unknown runtime '" + args[0] + "'. Current runtime: " + SharedRuntimeState.GetRuntimeInfo(true)); } else if (!SharedRuntimeState.IsRuntimeLoaded(runtime)) { FMessage.Log(runtime + " isn't loaded. Current runtime: " + SharedRuntimeState.GetRuntimeInfo(true)); } else if (SharedRuntimeState.Instance->NextRuntime != EDotNetRuntime.None) { FMessage.Log("Runtime change already queued (" + SharedRuntimeState.Instance->NextRuntime.ToString() + ")"); } else if (SharedRuntimeState.Instance->Reload) { FMessage.Log("The active runtime is currently reloading (" + SharedRuntimeState.Instance->ActiveRuntime + ")"); } else if (SharedRuntimeState.Instance->ActiveRuntime == runtime) { FMessage.Log(runtime.ToString() + " is already the active runtime"); } else { SharedRuntimeState.Instance->RuntimeCounter++; SharedRuntimeState.Instance->NextRuntime = runtime; FMessage.Log("Changing runtime to " + runtime.ToString() + "..."); } } else { FMessage.Log(ELogVerbosity.Error, enableMoreRuntimesStr); FMessage.Log("Runtime: " + SharedRuntimeState.GetRuntimeInfo(true)); } } else { if (!SharedRuntimeState.HaveMultipleRuntimesLoaded()) { FMessage.Log(enableMoreRuntimesStr); } FMessage.Log("Runtime: " + SharedRuntimeState.GetRuntimeInfo(true)); } }
private static void LogFatal(string str) { FMessage.Log(ELogVerbosity.Fatal, str); }
private string GetModuleNamespace(UField field, out UnrealModuleType moduleAssetType, bool allowFoldersAsNamespace = true) { moduleAssetType = UnrealModuleType.Unknown; UPackage package = field.GetOutermost(); if (package != null) { CachedNamespace cachedNamespace; if (namespaceCache.TryGetValue(package, out cachedNamespace)) { moduleAssetType = cachedNamespace.ModuleAssetType; return(cachedNamespace.Namespace); } UnrealModuleType moduleType = UnrealModuleType.Unknown; moduleAssetType = UnrealModuleType.Unknown; string packageFilename = package.FileName.ToString(); if (string.IsNullOrEmpty(packageFilename.ToString()) || packageFilename == FName.None.ToString()) { packageFilename = field.GetPathName(); } string moduleName = FPackageName.GetShortName(package.GetName()); if (packageFilename.StartsWith("/Script")) { if (!modulesByName.TryGetValue(new FName(moduleName), out moduleType)) { moduleType = UnrealModuleType.Unknown; FMessage.Log(ELogVerbosity.Error, string.Format("Failed to find module for module '{0}'", moduleName)); } } else if (packageFilename.StartsWith("/Game/")) { moduleType = UnrealModuleType.Game; moduleAssetType = UnrealModuleType.Game; moduleName = FPaths.GetBaseFilename(FPaths.ProjectFilePath);// {Module} same as {Game} } else if (packageFilename.StartsWith("/Engine/")) { moduleType = UnrealModuleType.Game; moduleAssetType = UnrealModuleType.Engine; moduleName = Settings.Namespaces.Default; } else { string rootName = null; if (packageFilename.Length > 1 && packageFilename[0] == '/') { int slashIndex = packageFilename.IndexOf('/', 1); if (slashIndex >= 0) { rootName = packageFilename.Substring(1, slashIndex - 1); moduleName = rootName;// Update ModuleName for {Module} if (!modulesByName.TryGetValue(new FName(rootName), out moduleAssetType)) { moduleAssetType = UnrealModuleType.Unknown; } } } if (moduleAssetType == UnrealModuleType.Unknown) { FMessage.Log(ELogVerbosity.Error, string.Format("Unknown module asset type root:'{0}' path:'{1}' name:'{2}' path2:'{3}'", rootName, packageFilename, field.GetName(), field.GetPathName())); } moduleType = UnrealModuleType.Game; } if (moduleType != UnrealModuleType.Unknown) { string namespaceName = GetModuleNamespace(moduleType, moduleName, moduleAssetType, allowFoldersAsNamespace, packageFilename); namespaceCache[package] = new CachedNamespace(namespaceName, moduleName, moduleType, moduleAssetType); return(namespaceName); } else { FMessage.Log(ELogVerbosity.Error, string.Format("Unknown module type {0} {1}", packageFilename, moduleName)); } } return(null); }
private static bool Generate(string templateName) { if (!FBuild.WithEditor) { return(false); } if (templateName.Equals("Shared", StringComparison.OrdinalIgnoreCase)) { // The shared folder is reserved for shared content return(false); } GetPaths(); string templateDir = Path.Combine(templatesDir, templateName); if (!Directory.Exists(templateDir)) { FMessage.Log(ELogVerbosity.Error, "Couldn't find template '" + templateName + "' to generate the managed project from."); return(false); } if (!Directory.Exists(projectManagedDir)) { Directory.CreateDirectory(projectManagedDir); } if ((File.Exists(projectManagedCsProj) && !File.Exists(projectManagedSln)) || (!File.Exists(projectManagedCsProj) && File.Exists(projectManagedSln))) { // Something is wrong here. The .csproj or .sln exists without the other file. It could be that files were // moved around or deleted. We don't want to potentially overwrite existing files so just print a warning instead. FMessage.Log(ELogVerbosity.Warning, "Found conflicting .sln/.csproj files when attempting to generate a C# project from the template '" + templateName + "'. " + "If you were expecting project files to be generated try deleting the .sln / .csproj and reopen the editor.\n" + "Solution: " + projectManagedSln + "\nProject: " + projectManagedCsProj); return(false); } if (!File.Exists(projectManagedCsProj)) { if (!Directory.Exists(projectManagedCsProjDir)) { Directory.CreateDirectory(projectManagedCsProjDir); } // Remove obj/bin directories if they exist string[] deleteDirs = { Path.Combine(projectManagedCsProjDir, "obj"), Path.Combine(projectManagedCsProjDir, "bin"), }; foreach (string dir in deleteDirs) { try { if (Directory.Exists(dir)) { Directory.Delete(dir, true); } } catch { } } // Copy the template / shared folder over to the project folder string[] rootDirs = { Path.Combine(templatesDir, "Shared"), templateDir }; foreach (string rootDir in rootDirs) { if (Directory.Exists(rootDir)) { foreach (string dir in Directory.GetDirectories(rootDir)) { DirectoryInfo directoryInfo = new DirectoryInfo(dir); if (directoryInfo.Name.Equals("Managed", StringComparison.OrdinalIgnoreCase)) { // /Templates/XXXX/Managed/ should be copied to the target csproj directory CopyFilesRecursive(directoryInfo, new DirectoryInfo(projectManagedCsProjDir), true); } else { // All other folders should be merged into the root project directory CopyFilesRecursive(directoryInfo, new DirectoryInfo(Path.Combine(projectDir, directoryInfo.Name)), true); } } } } // Copy /Templates/USharpProject.props to /ProjectName/Managed/USharpProject.props CopyFile(Path.Combine(templatesDir, "USharpProject.props"), projectManagedPropsFile, true); // This uri isn't really correct but if we don't provide "__relative__" we have the folder name in the path // which isn't what we want Uri csprojRelDir = new Uri(Path.Combine(projectManagedCsProjDir, "__relative__"), UriKind.Absolute); List <string> sourceFiles = new List <string>(); foreach (string sourceFile in Directory.GetFiles(projectManagedCsProjDir, "*.cs", SearchOption.AllDirectories)) { string relativePath = csprojRelDir.MakeRelativeUri(new Uri(sourceFile, UriKind.Absolute)).ToString(); sourceFiles.Add(NormalizePath(relativePath)); } // TODO: Determine if sdk or old style projects should be used bool sdkStyle = false; Guid solutionGuid = Guid.NewGuid(); Guid projectGuid = Guid.NewGuid(); GenerateProjectFile(projectGuid, sdkStyle, sourceFiles.ToArray()); GenerateSln(solutionGuid, projectGuid, sdkStyle); UpdatePropsFile(true); return(true); } return(false); }
private static void Log(ELogVerbosity verbosity, string str) { FMessage.Log(verbosity, str); }
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 "engine": loadMode = CodeGenerator.AssetLoadMode.Engine; 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) { codeGenerator = new CodeGenerator(); // Tests / using these for types for use in this lib //codeGenerator.Settings.CheckUObjectDestroyed = false; //codeGenerator.Settings.GenerateIsValidSafeguards = false; //codeGenerator.Settings.ExportMode = CodeGeneratorSettings.CodeExportMode.All; //codeGenerator.Settings.ExportAllFunctions = true; //codeGenerator.Settings.ExportAllProperties = true; //codeGenerator.Settings.MergeEnumFiles = false; codeGenerator.GenerateCodeForModule(args[1], true); } else { invalidArgs = true; } 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); } }
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); } }
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(); }
protected virtual void CallMe123_Implementation(int a1) { FMessage.Log("Hi from MyClassImpl " + a1); }