/// <summary> /// Read config settings for the given object /// </summary> /// <param name="ProjectDir">Path to the project directory</param> /// <param name="Platform">The platform being built</param> /// <param name="TargetObject">Object to receive the settings</param> public static void ReadSettings(DirectoryReference ProjectDir, UnrealTargetPlatform Platform, object TargetObject) { List <ConfigField> Fields = FindConfigFieldsForType(TargetObject.GetType()); foreach (ConfigField Field in Fields) { // Read the hierarchy listed ConfigHierarchy Hierarchy = ReadHierarchy(Field.Attribute.ConfigType, ProjectDir, Platform); // Parse the values from the config files and update the target object if (Field.AddElement == null) { string Text; if (Hierarchy.TryGetValue(Field.Attribute.SectionName, Field.Attribute.KeyName ?? Field.FieldInfo.Name, out Text)) { object Value; if (TryParseValue(Text, Field.FieldInfo.FieldType, out Value)) { Field.FieldInfo.SetValue(TargetObject, Value); } } } else { IEnumerable <string> Items; if (Hierarchy.TryGetValues(Field.Attribute.SectionName, Field.Attribute.KeyName ?? Field.FieldInfo.Name, out Items)) { foreach (string Item in Items) { object Value; if (TryParseValue(Item, Field.ElementType, out Value)) { Field.AddElement(TargetObject, Value); } } } } } }
/// <summary> /// Checks if the editor is currently running and this is a hot-reload /// </summary> public static bool ShouldDoHotReloadFromIDE(BuildConfiguration BuildConfiguration, TargetDescriptor TargetDesc) { // Check if Hot-reload is disabled globally for this project ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(TargetDesc.ProjectFile), TargetDesc.Platform); bool bAllowHotReloadFromIDE; if (Hierarchy.TryGetValue("BuildConfiguration", "bAllowHotReloadFromIDE", out bAllowHotReloadFromIDE) && !bAllowHotReloadFromIDE) { return(false); } if (!BuildConfiguration.bAllowHotReloadFromIDE) { return(false); } // Check if we're using LiveCode instead ConfigHierarchy EditorPerProjectHierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.EditorPerProjectUserSettings, DirectoryReference.FromFile(TargetDesc.ProjectFile), TargetDesc.Platform); bool bEnableLiveCode; if (EditorPerProjectHierarchy.GetBool("/Script/LiveCoding.LiveCodingSettings", "bEnabled", out bEnableLiveCode) && bEnableLiveCode) { return(false); } bool bIsRunning = false; // @todo ubtmake: Kind of cheating here to figure out if an editor target. At this point we don't have access to the actual target description, and // this code must be able to execute before we create or load module rules DLLs so that hot reload can work with bUseUBTMakefiles if (TargetDesc.Name.EndsWith("Editor", StringComparison.OrdinalIgnoreCase)) { string EditorBaseFileName = "UE4Editor"; if (TargetDesc.Configuration != UnrealTargetConfiguration.Development) { EditorBaseFileName = String.Format("{0}-{1}-{2}", EditorBaseFileName, TargetDesc.Platform, TargetDesc.Configuration); } FileReference EditorLocation; if (TargetDesc.Platform == UnrealTargetPlatform.Win64) { EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Win64", String.Format("{0}.exe", EditorBaseFileName)); } else if (TargetDesc.Platform == UnrealTargetPlatform.Mac) { EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Mac", String.Format("{0}.app/Contents/MacOS/{0}", EditorBaseFileName)); } else if (TargetDesc.Platform == UnrealTargetPlatform.Linux) { EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Linux", EditorBaseFileName); } else { throw new BuildException("Unknown editor filename for this platform"); } using (Timeline.ScopeEvent("Finding editor processes for hot-reload")) { DirectoryReference EditorRunsDir = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Intermediate", "EditorRuns"); if (!DirectoryReference.Exists(EditorRunsDir)) { return(false); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64) { foreach (FileReference EditorInstanceFile in DirectoryReference.EnumerateFiles(EditorRunsDir)) { int ProcessId; if (!Int32.TryParse(EditorInstanceFile.GetFileName(), out ProcessId)) { FileReference.Delete(EditorInstanceFile); continue; } Process RunningProcess; try { RunningProcess = Process.GetProcessById(ProcessId); } catch { RunningProcess = null; } if (RunningProcess == null) { FileReference.Delete(EditorInstanceFile); continue; } FileReference MainModuleFile; try { MainModuleFile = new FileReference(RunningProcess.MainModule.FileName); } catch { MainModuleFile = null; } if (!bIsRunning && EditorLocation == MainModuleFile) { bIsRunning = true; } } } else { FileInfo[] EditorRunsFiles = new DirectoryInfo(EditorRunsDir.FullName).GetFiles(); BuildHostPlatform.ProcessInfo[] Processes = BuildHostPlatform.Current.GetProcesses(); foreach (FileInfo File in EditorRunsFiles) { int PID; BuildHostPlatform.ProcessInfo Proc = null; if (!Int32.TryParse(File.Name, out PID) || (Proc = Processes.FirstOrDefault(P => P.PID == PID)) == default(BuildHostPlatform.ProcessInfo)) { // Delete stale files (it may happen if editor crashes). File.Delete(); continue; } // Don't break here to allow clean-up of other stale files. if (!bIsRunning) { // Otherwise check if the path matches. bIsRunning = new FileReference(Proc.Filename) == EditorLocation; } } } } } return(bIsRunning); }