public async Task FauxLocalFarm(string scenario, string bsp, string lightmapGroup, string quality, int clientCount, bool useFast, bool instanceOutput, ICancellableProgress <int> progress) { progress.MaxValue += 1 + 1 + 5 * (clientCount + 1) + 1 + 3; // first sync progress.Status = "Syncing faux (this might take a while)..."; await FauxSync(scenario, bsp, instanceOutput, useFast); progress.Report(1); int jobID = FauxCalculateJobID(scenario, bsp); string blobDirectory = $"faux\\{jobID}"; string clientCountStr = clientCount.ToString(); // cache ToolType tool = useFast ? ToolType.ToolFast : ToolType.Tool; async Task <Utility.Process.Result?> RunFastool(List <string> arguments, bool useShell) { Utility.Process.Result?result = await RunTool(tool, arguments, useShell, progress.GetCancellationToken()); progress.Report(1); if (result is not null && result.HasErrorOccured) { Debug.Print($"A lightmap command ({arguments}) has crashed, aborting"); progress.Cancel("Tool has crashed, canceling lightmaps..."); } return(result); } async Task <StageResult> RunStage(string stage) { progress.Status = $"Running stage: \"{stage}\" client count: {clientCount}"; var instances = new List <Task <Utility.Process.Result?> >(); for (int clientIdx = 0; clientIdx < clientCount; clientIdx++) { instances.Add(RunFastool(new() { $"faux_farm_{stage}", blobDirectory, clientIdx.ToString(), clientCountStr }, false)); } await Task.WhenAll(instances); // wait till workers exit bool worked = instances.TrueForAll(result => result.Result is not null && result.Result.Success); if (!worked) { Debug.Print("Some instance crashed todo (numm005): do something here"); //return StageResult.ClientFail; } progress.Status = $"Merging results from stage: \"{stage}\""; // todo(num005): handle workers crashing in a better way than just aborting // merge results from workers await RunFastool(new() { $"faux_farm_{stage}_merge", blobDirectory, clientCountStr }, instanceOutput); return(StageResult.Sucesss); } // start farm progress.Status = "Initializing lightmap farm..."; await RunFastool(new() { "faux_farm_begin", scenario, bsp, lightmapGroup, quality, jobID.ToString() }, instanceOutput); // run farm await RunStage("dillum"); await RunStage("pcast"); await RunStage("radest"); await RunStage("extillum"); await RunStage("fgather"); // end farm progress.Status = "Ending lightmap farm..."; await RunFastool(new() { "faux_farm_finish", blobDirectory }, instanceOutput); // todo(num0005): are all these strictly required? progress.Status = "A few final steps..."; await RunFastool(new() { "faux-build-linear-textures-with-intensity-from-quadratic", scenario, bsp }, instanceOutput); await RunFastool(new() { "faux-compress-scenario-bitmaps-dxt5", scenario, bsp }, instanceOutput); await RunFastool(new() { "faux-farm-compression-merge", scenario, bsp }, instanceOutput); }
public override async Task BuildLightmap(string scenario, string bsp, LightmapArgs args, ICancellableProgress <int>?progress) { string quality = GetLightmapQuality(args); if (args.instanceCount > 1 && (Profile.BuildType == build_type.release_mcc || Profile.CommunityTools)) // multi instance? { if (progress is not null) { progress.MaxValue += 1 + args.instanceCount; } async Task RunInstance(int index) { if (index == 0 && !Profile.IsH2Codez()) // not needed for H2Codez { if (progress is not null) { progress.Status = "Delaying launch of zeroth instance"; } await Task.Delay(1000 * 70, progress.GetCancellationToken()); } Utility.Process.Result result = await RunLightmapWorker( scenario, bsp, quality, args.instanceCount, index, args.NoAssert, progress.GetCancellationToken(), args.instanceOutput ); if (result is not null && result.HasErrorOccured) { progress.Cancel($"Tool worker {index} has failed - exit code {result.ReturnCode}"); } if (progress is not null) { progress.Report(1); } } var instances = new List <Task>(); for (int i = args.instanceCount - 1; i >= 0; i--) { instances.Add(RunInstance(i)); } if (progress is not null) { progress.Status = $"Running {args.instanceCount} instances"; } await Task.WhenAll(instances); if (progress is not null) { progress.Status = "Merging output"; } await RunMergeLightmap(scenario, bsp, args.instanceCount, args.NoAssert); if (progress is not null) { progress.Report(1); } } else { Debug.Assert(args.instanceCount == 1); // should be one, otherwise we got bad args if (progress is not null) { progress.DisableCancellation(); progress.MaxValue += 1; } await RunTool((args.NoAssert && Profile.BuildType == build_type.release_mcc)?ToolType.ToolFast : ToolType.Tool, new() { "lightmaps", scenario, bsp, quality }); if (progress is not null) { progress.Report(1); } } }