public void Args_ShouldCreateProperArgsWithDefines() { string outputAssembly = "myapp.dll"; BuildTask build = new BuildTask("csc.exe", "library").OutputFileTo(outputAssembly).DefineSymbol("NET20").DefineSymbol("TEST"); build.BuildArgs(); Assert.That(build._argumentBuilder.Build().Trim(), Is.EqualTo(String.Format("/out:\"{0}\" /target:{1} /define:NET20 /define:TEST", outputAssembly, "library"))); }
public void Args_ShouldAddAdditionalArgsWithValue() { string outputAssembly = "myapp.dll"; BuildTask build = new BuildTask("csc.exe", "library").OutputFileTo(outputAssembly).AddArgument("key", "value"); build.BuildArgs(); Assert.That(build._argumentBuilder.Build().Trim(), Is.EqualTo(String.Format("/key:value /out:\"{0}\" /target:{1}", outputAssembly, "library"))); }
public void AddBuildTask(BuildTask buildTask) { if ((this.BuildTasks != null)) { this.BuildTasks.Add(buildTask); } else { this.BuildTasks = new List<BuildTask>(); this.BuildTasks.Add(buildTask); } }
public void AddResource_ShouldAddSingleFileResource() { var fileName = "blah.txt"; var build = new BuildTask("csc.exe", "library").AddResource(fileName); var resrouce = build.Resources[0]; Assert.That(resrouce, Is.Not.Null); Assert.That(resrouce.FilePath, Is.EqualTo(fileName)); Assert.That(resrouce.Identifier, Is.EqualTo(null)); }
public void Args_ShouldCreateProperArgs_With_Fileset_Resources() { string reference = "external.dll"; string outputAssembly = "myapp.dll"; string source = "myfile.cs"; FileSet sources = new FileSet().Include(source); BuildTask build = new BuildTask("", "library").OutputFileTo(outputAssembly).AddResources(sources); build.BuildArgs(); Assert.That(build._argumentBuilder.Build().Trim(), Is.EqualTo(String.Format("/out:\"{0}\" /resource:\"myfile.cs\" /target:{1}", outputAssembly, "library"))); }
private void OnTaskStarted(BuildTask task) { if (_process != null) { _logger.LogDebug($"OnTaskStarted: {_process.Name}: {task.Node.Name}"); var node = task.Node; var warningTimeout = node.Args.Get("warning_timeout"); if (!string.IsNullOrEmpty(warningTimeout)) { if (Utils.TryParseTimeSpan(warningTimeout, out TimeSpan span)) { _logger.LogDebug($"WarningTimeout: {warningTimeout} ({span})"); StartWarningTimer(task.Node.Name, span); } } var now = DateTime.Now; if (now > _lastMessageTime.Add(_minInterval)) { CallStatus(); _lastMessageTime = now; } } }
static IEnumerator BuildModRoutine(FileInfo outputPath, BuildTask <BuildOutput> task) { if (task == null) { task = new BuildTask <BuildOutput>(); } yield return(BuildPartialModAsmRoutine(outputPath, task)); if (!task.Result.Success) { yield break; } task.Result.Success = false; yield return(BuildWeaverCoreGameRoutine(null, task)); if (!task.Result.Success) { yield break; } var weaverCoreOutputLocation = PathUtilities.AddSlash(outputPath.Directory.FullName) + "WeaverCore.dll"; File.Copy(WeaverCoreBuildLocation.FullName, weaverCoreOutputLocation, true); BundleTools.BuildAndEmbedAssetBundles(outputPath, new FileInfo(weaverCoreOutputLocation), typeof(BuildTools).GetMethod(nameof(StartHollowKnight))); }
protected override void PlanJob() { _task = new BuildTask(_plan, _worker.MotionComponent, GetDestinationNode().Position) as ITask; _task.ResultHandler += OnJobFinish; _worker.CommandProcessor.AddTask(_task); }
static IEnumerator BuildAssembly(BuildParameters parameters, BuildPresetType presetType, BuildTask <BuildOutput> task) { if (task.Result == null) { task.Result = new BuildOutput(); } else { task.Result.Success = false; } var builder = new AssemblyCompiler(); builder.BuildDirectory = parameters.BuildDirectory; builder.FileName = parameters.FileName; builder.Scripts = parameters.Scripts; builder.Target = parameters.Target; builder.TargetGroup = parameters.Group; builder.References = parameters.AssemblyReferences; builder.ExcludedReferences = parameters.ExcludedReferences; builder.Defines = parameters.Defines; if (presetType == BuildPresetType.Game || presetType == BuildPresetType.Editor) { builder.AddUnityReferences(); } if (presetType == BuildPresetType.Game) { builder.RemoveEditorReferences(); } if (!parameters.BuildPath.Directory.Exists) { parameters.BuildPath.Directory.Create(); } if (parameters.BuildPath.Exists) { parameters.BuildPath.Delete(); } AssemblyCompiler.OutputDetails output = new AssemblyCompiler.OutputDetails(); yield return(builder.Build(output)); if (output.Success) { task.Result.OutputFiles.Add(parameters.BuildPath); } task.Result.Success = output.Success; task.Completed = true; }
protected override async Task RunTestAsync() { Jenkins.MainLog.WriteLine("Running '{0}' on device (candidates: '{1}')", ProjectFile, string.Join("', '", Candidates.Select((v) => v.Name).ToArray())); var uninstall_log = Logs.Create($"uninstall-{Timestamp}.log", "Uninstall log"); using (var device_resource = await NotifyBlockingWaitAsync(Jenkins.GetDeviceResources(Candidates).AcquireAnyConcurrentAsync())) { try { // Set the device we acquired. Device = Candidates.First((d) => d.UDID == device_resource.Resource.Name); if (Device.DevicePlatform == DevicePlatform.watchOS) { CompanionDevice = Jenkins.Devices.FindCompanionDevice(Jenkins.DeviceLoadLog, Device); } Jenkins.MainLog.WriteLine("Acquired device '{0}' for '{1}'", Device.Name, ProjectFile); runner = new AppRunner { Harness = Harness, ProjectFile = ProjectFile, Target = AppRunnerTarget, LogDirectory = LogDirectory, MainLog = uninstall_log, DeviceName = Device.Name, CompanionDeviceName = CompanionDevice?.Name, Configuration = ProjectConfiguration, TimeoutMultiplier = TimeoutMultiplier, Variation = Variation, BuildTask = BuildTask, }; // Sometimes devices can't upgrade (depending on what has changed), so make sure to uninstall any existing apps first. if (Jenkins.UninstallTestApp) { runner.MainLog = uninstall_log; var uninstall_result = await runner.UninstallAsync(); if (!uninstall_result.Succeeded) { MainLog.WriteLine($"Pre-run uninstall failed, exit code: {uninstall_result.ExitCode} (this hopefully won't affect the test result)"); } } else { uninstall_log.WriteLine($"Pre-run uninstall skipped."); } if (!Failed) { // Install the app this.install_log = new AppInstallMonitorLog(Logs.Create($"install-{Timestamp}.log", "Install log")); try { runner.MainLog = this.install_log; var install_result = await runner.InstallAsync(install_log.CancellationToken); if (!install_result.Succeeded) { FailureMessage = $"Install failed, exit code: {install_result.ExitCode}."; ExecutionResult = TestExecutingResult.Failed; if (Harness.InCI) { XmlResultParser.GenerateFailure(Logs, "install", runner.AppName, runner.Variation, $"AppInstallation on {runner.DeviceName}", $"Install failed on {runner.DeviceName}, exit code: {install_result.ExitCode}", install_log.FullPath, Harness.XmlJargon); } } } finally { this.install_log.Dispose(); this.install_log = null; } } if (!Failed) { // Run the app runner.MainLog = Logs.Create($"run-{Device.UDID}-{Timestamp}.log", "Run log"); await runner.RunAsync(); if (!string.IsNullOrEmpty(runner.FailureMessage)) { FailureMessage = runner.FailureMessage; } else if (runner.Result != TestExecutingResult.Succeeded) { FailureMessage = GuessFailureReason(runner.MainLog); } if (runner.Result == TestExecutingResult.Succeeded && Platform == TestPlatform.iOS_TodayExtension64) { // For the today extension, the main app is just a single test. // This is because running the today extension will not wake up the device, // nor will it close & reopen the today app (but launching the main app // will do both of these things, preparing the device for launching the today extension). AppRunner todayRunner = new AppRunner { Harness = Harness, ProjectFile = TestProject.GetTodayExtension().Path, Target = AppRunnerTarget, LogDirectory = LogDirectory, MainLog = Logs.Create($"extension-run-{Device.UDID}-{Timestamp}.log", "Extension run log"), DeviceName = Device.Name, CompanionDeviceName = CompanionDevice?.Name, Configuration = ProjectConfiguration, Variation = Variation, BuildTask = BuildTask, }; additional_runner = todayRunner; await todayRunner.RunAsync(); foreach (var log in todayRunner.Logs.Where((v) => !v.Description.StartsWith("Extension ", StringComparison.Ordinal))) { log.Description = "Extension " + log.Description [0].ToString().ToLower() + log.Description.Substring(1); } ExecutionResult = todayRunner.Result; if (!string.IsNullOrEmpty(todayRunner.FailureMessage)) { FailureMessage = todayRunner.FailureMessage; } } else { ExecutionResult = runner.Result; } } } finally { // Uninstall again, so that we don't leave junk behind and fill up the device. if (Jenkins.UninstallTestApp) { runner.MainLog = uninstall_log; var uninstall_result = await runner.UninstallAsync(); if (!uninstall_result.Succeeded) { MainLog.WriteLine($"Post-run uninstall failed, exit code: {uninstall_result.ExitCode} (this won't affect the test result)"); } } else { uninstall_log.WriteLine($"Post-run uninstall skipped."); } // Also clean up after us locally. if (Harness.InCI || Jenkins.CleanSuccessfulTestRuns && Succeeded) { await BuildTask.CleanAsync(); } } } }
public void build(PrimitiveList primitives) { UI.printDetailed(UI.Module.ACCEL, "KDTree settings"); UI.printDetailed(UI.Module.ACCEL, " * Max Leaf Size: {0}", maxPrims); UI.printDetailed(UI.Module.ACCEL, " * Max Depth: {0}", MAX_DEPTH); UI.printDetailed(UI.Module.ACCEL, " * Traversal cost: {0}", TRAVERSAL_COST); UI.printDetailed(UI.Module.ACCEL, " * Intersect cost: {0}", INTERSECT_COST); UI.printDetailed(UI.Module.ACCEL, " * Empty bonus: {0}", EMPTY_BONUS); UI.printDetailed(UI.Module.ACCEL, " * Dump leaves: {0}", dump ? "enabled" : "disabled"); Timer total = new Timer(); total.start(); this.primitiveList = primitives; // get the object space bounds bounds = primitives.getWorldBounds(null); int nPrim = primitiveList.getNumPrimitives(), nSplits = 0; BuildTask task = new BuildTask(nPrim); Timer prepare = new Timer(); prepare.start(); for (int i = 0; i < nPrim; i++) { for (int axis = 0; axis < 3; axis++) { float ls = primitiveList.getPrimitiveBound(i, 2 * axis + 0); float rs = primitiveList.getPrimitiveBound(i, 2 * axis + 1); if (ls == rs) { // flat in this dimension task.splits[nSplits] = pack(ls, PLANAR, axis, i); nSplits++; } else { task.splits[nSplits + 0] = pack(ls, OPENED, axis, i); task.splits[nSplits + 1] = pack(rs, CLOSED, axis, i); nSplits += 2; } } } task.n = nSplits; prepare.end(); Timer t = new Timer(); List <int> tempTree = new List <int>(); List <int> tempList = new List <int>(); tempTree.Add(0); tempTree.Add(1); t.start(); // sort it Timer sorting = new Timer(); sorting.start(); radix12(task.splits, task.n); sorting.end(); // build the actual tree BuildStats stats = new BuildStats(); buildTree(bounds.getMinimum().x, bounds.getMaximum().x, bounds.getMinimum().y, bounds.getMaximum().y, bounds.getMinimum().z, bounds.getMaximum().z, task, 1, tempTree, 0, tempList, stats); t.end(); // write out arrays // free some memory task = null; tree = tempTree.ToArray(); tempTree = null; this.primitives = tempList.ToArray(); tempList = null; total.end(); // display some extra info stats.printStats(); UI.printDetailed(UI.Module.ACCEL, " * Node memory: {0}", Memory.SizeOf(tree)); UI.printDetailed(UI.Module.ACCEL, " * Object memory: {0}", Memory.SizeOf(this.primitives)); UI.printDetailed(UI.Module.ACCEL, " * Prepare time: {0}", prepare); UI.printDetailed(UI.Module.ACCEL, " * Sorting time: {0}", sorting); UI.printDetailed(UI.Module.ACCEL, " * Tree creation: {0}", t); UI.printDetailed(UI.Module.ACCEL, " * Build time: {0}", total); if (dump) { try { UI.printInfo(UI.Module.ACCEL, "Dumping mtls to {0}.mtl ...", dumpPrefix); StreamWriter mtlFile = new StreamWriter(dumpPrefix + ".mtl"); int maxN = stats.maxObjects; for (int n = 0; n <= maxN; n++) { float blend = (float)n / (float)maxN; Color nc; if (blend < 0.25) { nc = Color.blend(Color.BLUE, Color.GREEN, blend / 0.25f); } else if (blend < 0.5) { nc = Color.blend(Color.GREEN, Color.YELLOW, (blend - 0.25f) / 0.25f); } else if (blend < 0.75) { nc = Color.blend(Color.YELLOW, Color.RED, (blend - 0.50f) / 0.25f); } else { nc = Color.MAGENTA; } mtlFile.WriteLine(string.Format("newmtl mtl{0}", n)); float[] rgb = nc.getRGB(); mtlFile.WriteLine("Ka 0.1 0.1 0.1"); mtlFile.WriteLine(string.Format("Kd {0}g {1}g {2}g", rgb[0], rgb[1], rgb[2])); mtlFile.WriteLine("illum 1\n"); } StreamWriter objFile = new StreamWriter(dumpPrefix + ".obj"); UI.printInfo(UI.Module.ACCEL, "Dumping tree to {0}.obj ...", dumpPrefix); dumpObj(0, 0, maxN, new BoundingBox(bounds), objFile, mtlFile); objFile.Close(); mtlFile.Close(); } catch (Exception e) { Console.WriteLine(e); } } }
private void buildTree(float minx, float maxx, float miny, float maxy, float minz, float maxz, BuildTask task, int depth, List<int> tempTree, int offset, List<int> tempList, BuildStats stats) { // get node bounding box extents if (task.numObjects > maxPrims && depth < MAX_DEPTH) { float dx = maxx - minx; float dy = maxy - miny; float dz = maxz - minz; // search for best possible split float bestCost = INTERSECT_COST * task.numObjects; int bestAxis = -1; int bestOffsetStart = -1; int bestOffsetEnd = -1; float bestSplit = 0; bool bestPlanarLeft = false; int bnl = 0, bnr = 0; // inverse area of the bounding box (factor of 2 ommitted) float area = (dx * dy + dy * dz + dz * dx); float ISECT_COST = INTERSECT_COST / area; // setup counts for each axis int[] nl = { 0, 0, 0 }; int[] nr = { task.numObjects, task.numObjects, task.numObjects }; // setup bounds for each axis float[] dp = { dy * dz, dz * dx, dx * dy }; float[] ds = { dy + dz, dz + dx, dx + dy }; float[] nodeMin = { minx, miny, minz }; float[] nodeMax = { maxx, maxy, maxz }; // search for best cost int nSplits = task.n; long[] splits = task.splits; byte[] lrtable = task.leftRightTable; for (int i = 0; i < nSplits; ) { // extract current split long ptr = splits[i]; float split = unpackSplit(ptr); int axis = unpackAxis(ptr); // mark current position int currentOffset = i; // count number of primitives start/stopping/lying on the // current plane int pClosed = 0, pPlanar = 0, pOpened = 0; long ptrMasked = (long)((ulong)ptr & (~((ulong)TYPE_MASK) & 0xFFFFFFFFF0000000L)); long ptrClosed = ptrMasked | CLOSED; long ptrPlanar = ptrMasked | PLANAR; long ptrOpened = ptrMasked | OPENED; while (i < nSplits && ((ulong)splits[i] & 0xFFFFFFFFF0000000L) == (ulong)ptrClosed) { int obj = unpackObject(splits[i]); lrtable[(uint)obj >> 2] = 0;//>>> pClosed++; i++; } while (i < nSplits && ((ulong)splits[i] & 0xFFFFFFFFF0000000L) == (ulong)ptrPlanar) { int obj = unpackObject(splits[i]); lrtable[(uint)obj >> 2] = 0;//>>> pPlanar++; i++; } while (i < nSplits && ((ulong)splits[i] & 0xFFFFFFFFF0000000L) == (ulong)ptrOpened) { int obj = unpackObject(splits[i]); lrtable[(uint)obj >> 2] = 0;//>>> pOpened++; i++; } // now we have summed all contributions from this plane nr[axis] -= pPlanar + pClosed; // compute cost if (split >= nodeMin[axis] && split <= nodeMax[axis]) { // left and right surface area (factor of 2 ommitted) float dl = split - nodeMin[axis]; float dr = nodeMax[axis] - split; float lp = dp[axis] + dl * ds[axis]; float rp = dp[axis] + dr * ds[axis]; // planar prims go to smallest cell always bool planarLeft = dl < dr; int numLeft = nl[axis] + (planarLeft ? pPlanar : 0); int numRight = nr[axis] + (planarLeft ? 0 : pPlanar); float eb = ((numLeft == 0 && dl > 0) || (numRight == 0 && dr > 0)) ? EMPTY_BONUS : 0; float cost = TRAVERSAL_COST + ISECT_COST * (1 - eb) * (lp * numLeft + rp * numRight); if (cost < bestCost) { bestCost = cost; bestAxis = axis; bestSplit = split; bestOffsetStart = currentOffset; bestOffsetEnd = i; bnl = numLeft; bnr = numRight; bestPlanarLeft = planarLeft; } } // move objects left nl[axis] += pOpened + pPlanar; } // debug check for correctness of the scan for (int axis = 0; axis < 3; axis++) { int numLeft = nl[axis]; int numRight = nr[axis]; if (numLeft != task.numObjects || numRight != 0) UI.printError(UI.Module.ACCEL, "Didn't scan full range of objects @depth={0}. Left overs for axis {1}: [L: {2}] [R: {3}]", depth, axis, numLeft, numRight); } // found best split? if (bestAxis != -1) { // allocate space for child nodes BuildTask taskL = new BuildTask(bnl, task); BuildTask taskR = new BuildTask(bnr, task); int lk = 0, rk = 0; for (int i = 0; i < bestOffsetStart; i++) { long ptr = splits[i]; if (unpackAxis(ptr) == bestAxis) { if (unpackSplitType(ptr) != CLOSED) { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(1 << ((obj & 3) << 1));//>>> lk++; } } } for (int i = bestOffsetStart; i < bestOffsetEnd; i++) { long ptr = splits[i]; Debug.Assert(unpackAxis(ptr) == bestAxis); if (unpackSplitType(ptr) == PLANAR) { if (bestPlanarLeft) { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(1 << ((obj & 3) << 1));//>>> lk++; } else { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(2 << ((obj & 3) << 1));//>>> rk++; } } } for (int i = bestOffsetEnd; i < nSplits; i++) { long ptr = splits[i]; if (unpackAxis(ptr) == bestAxis) { if (unpackSplitType(ptr) != OPENED) { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(2 << ((obj & 3) << 1));//>>> rk++; } } } // output new splits while maintaining order long[] splitsL = taskL.splits; long[] splitsR = taskR.splits; int nsl = 0, nsr = 0; for (int i = 0; i < nSplits; i++) { long ptr = splits[i]; int obj = unpackObject(ptr); int idx = (int)((uint)obj >> 2);//>>> int mask = 1 << ((obj & 3) << 1); if ((lrtable[idx] & mask) != 0) { splitsL[nsl] = ptr; nsl++; } if ((lrtable[idx] & (mask << 1)) != 0) { splitsR[nsr] = ptr; nsr++; } } taskL.n = nsl; taskR.n = nsr; // free more memory task.splits = splits = splitsL = splitsR = null; task = null; // allocate child nodes int nextOffset = tempTree.Count; tempTree.Add(0); tempTree.Add(0); tempTree.Add(0); tempTree.Add(0); // create current node tempTree[offset + 0] = (bestAxis << 30) | nextOffset; tempTree[offset + 1] = ByteUtil.floatToRawIntBits(bestSplit); // recurse for child nodes - free object arrays after each step stats.updateInner(); switch (bestAxis) { case 0: buildTree(minx, bestSplit, miny, maxy, minz, maxz, taskL, depth + 1, tempTree, nextOffset, tempList, stats); taskL = null; buildTree(bestSplit, maxx, miny, maxy, minz, maxz, taskR, depth + 1, tempTree, nextOffset + 2, tempList, stats); taskR = null; return; case 1: buildTree(minx, maxx, miny, bestSplit, minz, maxz, taskL, depth + 1, tempTree, nextOffset, tempList, stats); taskL = null; buildTree(minx, maxx, bestSplit, maxy, minz, maxz, taskR, depth + 1, tempTree, nextOffset + 2, tempList, stats); taskR = null; return; case 2: buildTree(minx, maxx, miny, maxy, minz, bestSplit, taskL, depth + 1, tempTree, nextOffset, tempList, stats); taskL = null; buildTree(minx, maxx, miny, maxy, bestSplit, maxz, taskR, depth + 1, tempTree, nextOffset + 2, tempList, stats); taskR = null; return; default: Debug.Assert(false); break; } } } // create leaf node int listOffset = tempList.Count; int n = 0; for (int i = 0; i < task.n; i++) { long ptr = task.splits[i]; if (unpackAxis(ptr) == 0 && unpackSplitType(ptr) != CLOSED) { tempList.Add(unpackObject(ptr)); n++; } } stats.updateLeaf(depth, n); if (n != task.numObjects) UI.printError(UI.Module.ACCEL, "Error creating leaf node - expecting {0} found {1}", task.numObjects, n); tempTree[offset + 0] = (3 << 30) | listOffset; tempTree[offset + 1] = task.numObjects; // free some memory task.splits = null; }
public BuildTask(int numObjects, BuildTask parent) { splits = new long[6 * numObjects]; this.numObjects = numObjects; n = 0; leftRightTable = parent.leftRightTable; }
public DbProjectTaskRecord(Guid projectID, BuildTask task, int taskNumber) { this.ProjectID = projectID; this.Expression = task.Expression; this.SuccessExitCodes = string.Join(",", task.SuccessfulExitCodes); }
private void OnTaskDone(BuildTask task) { StopWarningTimer(task.Node.Name); }
protected override void OnTaskStarted(BuildTask buildTask) { WriteLine(); WriteLine($"Task started: {buildTask.Node.Name}"); }
protected override void OnTaskDone(BuildTask buildTask) { WriteLine(); WriteLine($"Task done: {buildTask.Node.Name}"); WriteLine(GetTaskInfo(buildTask)); }
public static void ValidateConstructionSite(this BuildTask this_build_task, Builder builder) { //Find building complex our BuildTask is a part of List <BuildTask> build_task_segment = builder.Unit.Program .GetSegment(this_build_task) .Where(operation => operation is BuildTask && !((operation as BuildTask).Blueprint.HasComponent <Motile>())) .Select(operation => operation as BuildTask) .ToList(); int build_task_index = build_task_segment.IndexOf(this_build_task); List <BuildTask> complex = build_task_segment.GetRange(build_task_index, build_task_segment.Count - build_task_index); //Determine if building complex is blocked bool complex_is_blocked = false; foreach (BuildTask build_task in complex) { if (!build_task.IsConstructionSiteClear) { complex_is_blocked = true; } } if (!complex_is_blocked) { return; } Sphere complex_bounding_sphere = MathUtility.GetBoundingSphere(complex .Select(build_task => new Sphere(build_task.ConstructionSite, build_task.ConstructionSiteSize))); Vector3 complex_center = complex_bounding_sphere.Point; float complex_radius = complex_bounding_sphere.Radius; //Get block structure and nearby buildings within those blocks. //A "block" is a collection buildings separated by space (i.e. roads) List <Graph> blocks = GraphUtility.GetBlocks( Scene.Main.World.Buildings .Select(building => new UnitData(building)), MaxBlockNeighborDistance); HashSet <Node> nearby_building_nodes = new HashSet <Node>(); foreach (Graph block in blocks) { if (block.Nodes.FirstOrDefault(node => node.GetPosition().Distance(complex_center) < complex_radius * 8) != null) { nearby_building_nodes.UnionWith(block.Nodes); } } //Finds all blocks that would be effected by a candidate construction site. //"Effected" here means they would aquire new nodes because we would //be building new buildings on that block. Dictionary <Vector3, Dictionary <Graph, Dictionary <BuildTask, int> > > blocks_abutted_map = new Dictionary <Vector3, Dictionary <Graph, Dictionary <BuildTask, int> > >(); System.Func <Vector3, Dictionary <Graph, Dictionary <BuildTask, int> > > GetBlocksAbutted = delegate(Vector3 candidate_site) { if (!blocks_abutted_map.ContainsKey(candidate_site)) { Vector3 displacement = candidate_site - complex_center; Dictionary <Graph, Dictionary <BuildTask, int> > blocks_abutted = new Dictionary <Graph, Dictionary <BuildTask, int> >(); foreach (BuildTask build_task in complex) { Vector3 new_construction_site = build_task.ConstructionSite + displacement; foreach (Graph block in blocks) { foreach (Node node in block.Nodes) { if (new_construction_site.Distance(node.GetPosition()) < (build_task.ConstructionSiteSize + node.GetSize() + BlockMargin)) { if (!blocks_abutted.ContainsKey(block)) { blocks_abutted[block] = new Dictionary <BuildTask, int>(); } if (!blocks_abutted[block].ContainsKey(build_task)) { blocks_abutted[block][build_task] = 0; } blocks_abutted[block][build_task]++; } } } } blocks_abutted_map[candidate_site] = blocks_abutted; } return(blocks_abutted_map[candidate_site]); }; //Estimating the connectivity that would result //from a candidate construction site. Assumes candidate would //only abut one block, and that that the resultant connectivity //would only depend on the buildings that directly abut the block //(Ignoring new buildings that abut the abutting buildings) Dictionary <Vector3, float> resultant_connectivity_map = new Dictionary <Vector3, float>(); System.Func <Vector3, float> EstimateResultantConnectivity = delegate(Vector3 candidate_site) { if (!resultant_connectivity_map.ContainsKey(candidate_site)) { Dictionary <Graph, Dictionary <BuildTask, int> > blocks_abutted = GetBlocksAbutted(candidate_site); //We assume blocks abutted count > 0, because otherwise, we shouldn't //be collided in the first place, right? If this assumption does not //hold, we need some sort of special handling because such a //candidate will not have a connectivity metric. Debug.Assert(blocks_abutted.Keys.Count() > 0, "candidate site does not abut any existing blocks"); Graph abutting_block = blocks_abutted.Keys.First(); int new_edges = 0; int new_nodes = 0; foreach (BuildTask build_task in blocks_abutted[abutting_block].Keys) { new_nodes++; new_edges += abutting_block.Nodes .Where(node => node.GetPosition().Distance(candidate_site) < (MaxBlockNeighborDistance + node.GetSize() + complex_radius)).Count() * 2; } resultant_connectivity_map[candidate_site] = (abutting_block.Connectivity * abutting_block.Nodes.Count() + new_edges) / (abutting_block.Nodes.Count() + new_nodes); } return(resultant_connectivity_map[candidate_site]); }; //Culls candidate construction sites based on a set of criteria, //such as collisions with existing features and topological //concerns with regards to transport. System.Func <Vector3, bool> IsCandidateSiteValid = delegate(Vector3 candidate_site) { //Not within terrain boundaries Terrain terrain = Scene.Main.World.Asteroid.Terrain; Vector2 normalized_xz = (candidate_site.XZ() - terrain.GetPosition().XZ()) / terrain.terrainData.size.XZ(); if (normalized_xz.x < 0 || normalized_xz.x > 1 || normalized_xz.y < 0 || normalized_xz.y > 1) { return(false); } //Too steep float slope_in_degrees = terrain.terrainData .GetSteepness(normalized_xz.x, normalized_xz.y); if (slope_in_degrees != 0) { if (slope_in_degrees > 20) { return(false); } } //Must be on the frontier of the abutting block. //This is to prevent winding and branching Sphere block_bounding_sphere = GetBlocksAbutted(candidate_site).Keys.First() .GetBoundingSphere(); float distance_to_center = candidate_site.Distance(block_bounding_sphere.Point); if ((block_bounding_sphere.Radius - distance_to_center) > (complex_radius + 1.2f)) { return(false); } //Collision with existing buildings foreach (Unit unit in Scene.Main.World.Buildings) { if (unit.Physical.Position.Distance(candidate_site) < (unit.Physical.Size + complex_radius)) { return(false); } } //Collision with highways if (Scene.Main.World.Asteroid.HighwaySystem .IsObstructingTraffic(candidate_site, complex_radius)) { return(false); } //Candidate might connect separate blocks together Dictionary <Graph, Dictionary <BuildTask, int> > blocks_abutted = GetBlocksAbutted(candidate_site); if (blocks_abutted.Keys.Count() > 1) { return(false); } //Would this increase connectivity to undesirable levels? //(Higher connectivity means lower surface area, //thus buildings may not be exposed to traffic) float connectivity = blocks_abutted.Keys.First().Connectivity; float resultant_connectivity = EstimateResultantConnectivity(candidate_site); if (connectivity >= MaxBlockConnectivity) { if (resultant_connectivity >= connectivity) { return(false); } } else if (resultant_connectivity > MaxBlockConnectivity) { return(false); } return(true); }; //Generate candidate construction sites by placing the building //complex center such that it "cuddles" two existing buildings //that neighbor one another. // ####### ####### // # # # # // # Building # # Building # // # A # # B # // # # # # // ####### ####### // > ####### < // / # # \ // / # Complex # \ // / # # \ // / # # \ // Cuddling ####### Cuddling System.Func <List <Vector3> > GenerateCandidateSites_Cuddle = delegate() { List <Vector3> candidate_sites_ = new List <Vector3>(); IEnumerable <Edge> edges = new Graph(nearby_building_nodes).Edges; foreach (Edge edge in edges) { Node a = edge.A, b = edge.B; if (b.GetUnit().Physical.Position.Distance(complex_center) < a.GetUnit().Physical.Position.Distance(complex_center)) { Utility.Swap(ref a, ref b); } Vector3 displacement = b.GetUnit().Physical.Position - a.GetUnit().Physical.Position; float space_between = displacement.magnitude - (a.GetSize() + b.GetSize()); if (complex_radius * 2 > space_between && blocks.Find(block => block.Nodes.Contains(a)).Nodes.Contains(b)) { float a_side = complex_radius + b.GetSize(), b_side = complex_radius + a.GetSize(); float a_angle = Mathf.Acos((Mathf.Pow(b_side, 2) + Mathf.Pow(displacement.magnitude, 2) - Mathf.Pow(a_side, 2)) / (2 * b_side * displacement.magnitude)); Vector3 direction = displacement.YChangedTo(0).normalized; Vector3 perpendicular_direction = direction.Crossed(new Vector3(0, 1, 0)); float direction_length = Mathf.Cos(a_angle) * b_side; float perpendicular_direction_length = Mathf.Sin(a_angle) * b_side * 1.01f; float height = Mathf.Lerp(a.GetPosition().y, b.GetPosition().y, direction_length / displacement.magnitude); candidate_sites_.Add(a.GetPosition().YChangedTo(height) + direction * direction_length + perpendicular_direction * perpendicular_direction_length); candidate_sites_.Add(a.GetPosition().YChangedTo(height) + direction * direction_length - perpendicular_direction * perpendicular_direction_length); } } return(candidate_sites_); }; //Generates candidate construction sites by computing the minimum //spanning tree of all nearby buildings and then attempts to place //complex between two neighboring buildings, as near as possible to the //building nearest to the original building complex center. System.Func <List <Vector3> > GenerateCandidateSites_Between = delegate() { List <Vector3> candidate_sites_ = new List <Vector3>(); Graph mst = GraphUtility.CreateHairball(nearby_building_nodes.Select(node => new UnitData(node.GetUnit()))) .MinimumSpanned_Euclidean(); foreach (Edge edge in mst.Edges) { Node a = edge.A, b = edge.B; if (b.GetUnit().Physical.Position.Distance(complex_center) < a.GetUnit().Physical.Position.Distance(complex_center)) { Utility.Swap(ref a, ref b); } Vector3 displacement = b.GetUnit().Physical.Position - a.GetUnit().Physical.Position; float space_between = displacement.magnitude - (a.GetSize() + b.GetSize()); if (complex_radius * 2 <= space_between && blocks.Find(block => block.Nodes.Contains(a)).Nodes.Contains(b)) { candidate_sites_.Add(complex_center + displacement.normalized * (a.GetSize() + complex_radius) * 1.01f); } } return(candidate_sites_); }; //Generates candidate construction sites by finding nearest building to //the original building complex center and then placing complex next to //that building in n equally spaced radial directions. System.Func <List <Vector3> > GenerateCandidateSites_Radial = delegate() { List <Vector3> candidate_sites_ = new List <Vector3>(); Unit nearest_building = nearby_building_nodes .MinElement(node => node.GetPosition().Distance(complex_center)) .GetUnit(); for (int i = 0; i < 10; i++) { float angle = (i / 10.0f) * (2 * Mathf.PI); candidate_sites_.Add(nearest_building.Physical.Position + new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * (nearest_building.Physical.Size + complex_radius) * 1.01f); } return(candidate_sites_); }; //Attempt to find valid candidate construction sites using each //of the generation functions. // 1) Generate candidate sites using next generation function // 2) Cull invalid sites // 3a) If no sites remain, return to step 1, unless // 3b) No generation functions remain. BuildTask is canceled. List <Vector3> candidate_sites = null; List <System.Func <List <Vector3> > > candidate_site_generators = Utility.List(GenerateCandidateSites_Cuddle, GenerateCandidateSites_Radial); foreach (System.Func <List <Vector3> > candidate_site_generator in candidate_site_generators) { candidate_sites = candidate_site_generator(); foreach (Vector3 candidate_site in new List <Vector3>(candidate_sites)) { if (!IsCandidateSiteValid(candidate_site)) { candidate_sites.Remove(candidate_site); } } if (candidate_sites.Count > 0) { break; } } if (candidate_sites.Count == 0) { builder.Unit.Task = null; return; } //Define metrics with which to judge valid candidate sites. //Metrics measure "badness", i.e. worse => higher number System.Func <Vector3, float> ConnectivityMetric = delegate(Vector3 candidate_site) { float connectivity = EstimateResultantConnectivity(candidate_site); int new_connections = GetBlocksAbutted(candidate_site).Values.First().Values.Sum(); if (connectivity > MaxBlockConnectivity) { return(new_connections); } return(-new_connections); }; System.Func <Vector3, float> TargetDistanceMetric = delegate(Vector3 candidate_site) { return(candidate_site.Distance(complex_center)); }; System.Func <Vector3, float> BuilderDistanceMetric = delegate(Vector3 candidate_site) { return(candidate_site.Distance(builder.Unit.Physical.Position)); }; System.Func <Vector3, float> LengthMetric = delegate(Vector3 candidate_site) { Graph block_abutted = GetBlocksAbutted(candidate_site).Keys.First(); return(-block_abutted.Nodes .Max(node => block_abutted.Nodes .Max(other_node => node.GetPosition().Distance(other_node.GetPosition())))); }; System.Func <Vector3, float> SmoothnessMetric = delegate(Vector3 candidate_site) { Graph block_abutted = GetBlocksAbutted(candidate_site).Keys.First(); return(-block_abutted.Nodes .Sum(node => node.GetPosition().Distance(candidate_site)) / block_abutted.Nodes.Count()); }; List <System.Func <Vector3, float> > metrics = Utility.List( ConnectivityMetric, TargetDistanceMetric, BuilderDistanceMetric, LengthMetric, SmoothnessMetric); Dictionary <System.Func <Vector3, float>, float> metric_weights = new Dictionary <System.Func <Vector3, float>, float>(); metric_weights[ConnectivityMetric] = 0.0f; metric_weights[TargetDistanceMetric] = 4.0f; metric_weights[BuilderDistanceMetric] = 4.0f; metric_weights[LengthMetric] = 3.0f; metric_weights[SmoothnessMetric] = 3.0f; //Score candidate construction sites by computing weighted //metrics and summing. Then, find minimum scored candidate //and update ConstructionSite of BuildTasks in complex Dictionary <Vector3, float> scores = new Dictionary <Vector3, float>(); foreach (Vector3 candidate_site in candidate_sites) { scores[candidate_site] = 0; foreach (System.Func <Vector3, float> metric in metrics) { if (metric_weights[metric] > 0) { scores[candidate_site] += metric(candidate_site) * metric_weights[metric]; } } } List <Vector3> sorted_candidate_sites = candidate_sites.Sorted(candidate_site => scores[candidate_site]); Vector3 complex_displacement = sorted_candidate_sites.First() - complex_center; foreach (BuildTask build_task in complex) { build_task.Input.PrimaryVariableName = Scene.Main.World.MemorizePosition(build_task.ConstructionSite + complex_displacement); } }
public void RemoveTask(BuildTask taskElement) { }
protected abstract void OnTaskDone(BuildTask buildTask);
protected abstract void OnTaskStarted(BuildTask buildTask);
public void Build_Library_MultipleFiles() { // Register the test process manager var processManager = new MockProcessManager(); // Register the test listener var testListener = new TestTraceListener(); using (var scopedTraceListener = new ScopedTraceListenerRegister(testListener)) using (var scopedProcesManager = new ScopedSingleton <IProcessManager>(processManager)) { // Setup the input build state var buildState = new MockBuildState(); var state = buildState.ActiveState; // Setup build table var buildTable = new ValueTable(); state.Add("Build", new Value(buildTable)); buildTable.Add("TargetName", new Value("Library")); buildTable.Add("TargetType", new Value((long)BuildTargetType.Library)); buildTable.Add("SourceRootDirectory", new Value("C:/source/")); buildTable.Add("TargetRootDirectory", new Value("C:/target/")); buildTable.Add("ObjectDirectory", new Value("obj/")); buildTable.Add("BinaryDirectory", new Value("bin/")); buildTable.Add("Source", new Value(new ValueList() { new Value("TestFile1.cpp"), new Value("TestFile2.cpp"), new Value("TestFile3.cpp"), })); buildTable.Add("IncludeDirectories", new Value(new ValueList() { new Value("Folder"), new Value("AnotherFolder/Sub"), })); buildTable.Add("ModuleDependencies", new Value(new ValueList() { new Value("../Other/bin/OtherModule1.mock.bmi"), new Value("../OtherModule2.mock.bmi"), })); buildTable.Add("OptimizationLevel", new Value((long)BuildOptimizationLevel.None)); // Setup parameters table var parametersTable = new ValueTable(); state.Add("Parameters", new Value(parametersTable)); parametersTable.Add("Architecture", new Value("x64")); parametersTable.Add("Compiler", new Value("MOCK")); // Register the mock compiler var compiler = new Compiler.Mock.Compiler(); var compilerFactory = new Dictionary <string, Func <IValueTable, ICompiler> >(); compilerFactory.Add("MOCK", (IValueTable state) => { return(compiler); }); var factory = new ValueFactory(); var uut = new BuildTask(buildState, factory, compilerFactory); uut.Execute(); // Verify expected process manager requests Assert.Equal( new List <string>() { "GetCurrentProcessFileName", "GetCurrentProcessFileName", "GetCurrentProcessFileName", }, processManager.GetRequests()); // Verify expected logs Assert.Equal( new List <string>() { "INFO: Build Generate Done", }, testListener.GetMessages()); // Setup the shared arguments var expectedCompileArguments = new CompileArguments() { Target = new Path("./bin/Library.mock.dll"), ReferenceTarget = new Path("./bin/ref/Library.mock.dll"), SourceRootDirectory = new Path("C:/source/"), TargetRootDirectory = new Path("C:/target/"), ObjectDirectory = new Path("obj/"), SourceFiles = new List <Path>() { new Path("TestFile1.cpp"), new Path("TestFile2.cpp"), new Path("TestFile3.cpp"), }, }; // Verify expected compiler calls Assert.Equal( new List <CompileArguments>() { expectedCompileArguments, }, compiler.GetCompileRequests()); // Verify build state var expectedBuildOperations = new List <BuildOperation>() { new BuildOperation( "MakeDir [./obj/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./obj/\"", new List <Path>(), new List <Path>() { new Path("./obj/"), }), new BuildOperation( "MakeDir [./bin/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/\"", new List <Path>(), new List <Path>() { new Path("./bin/"), }), new BuildOperation( "MakeDir [./bin/ref/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/ref/\"", new List <Path>(), new List <Path>() { new Path("./bin/ref/"), }), new BuildOperation( "MockCompile: 1", new Path("MockWorkingDirectory"), new Path("MockCompiler.exe"), "Arguments", new List <Path>() { new Path("./InputFile.in"), }, new List <Path>() { new Path("./OutputFile.out"), }), }; Assert.Equal( expectedBuildOperations, buildState.GetBuildOperations()); } }
public void Execute(BuildTask task) { var messagePane = Package.TundraOutputPane; var buildPane = Package.BuildOutputPane; try { Project proj = null; if (task == BuildTask.Compile) { proj = TundraPackage.GetProject(Package.DTE.ActiveDocument); } else { proj = Package.GetBuildProject(); } bool regularCommand = false; if (proj != null) { Match m = TundraPackage.GetBuildCommandLine(proj, proj.ConfigurationManager.ActiveConfiguration); if (m != null && m.Success) { Package.DTE.ExecuteCommand("File.SaveAll"); if (task == BuildTask.Compile && !Package.DTE.ActiveDocument.Saved) { Package.DTE.ActiveDocument.Save(); } try { var tundraPath = m.Groups[1].ToString(); var dir = m.Groups[2].ToString().Trim(new char[] { '"' }); var config = m.Groups[3].ToString(); string projects = string.Empty; string arguments = string.Empty; int projectCount = 0; if (task == BuildTask.Compile) { projects = proj.Name.ToString(); projectCount = 1; arguments = string.Format("\"{0}\" {1}", Package.DTE.ActiveDocument.FullName, config); } else { var projs = m.Groups[4].ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); projects = string.Join(" ", projs); projectCount = projs.Length; string arg = string.Empty; if (task == BuildTask.Clean) { arg = "--clean"; } else if (task == BuildTask.Rebuild) { arg = "--rebuild"; } arguments = string.Format("{0} {1} {2}", arg, config, m.Groups[4].ToString()); } var p = Package.CreateTundraProcess(tundraPath, dir, arguments); if (p == null) { throw new Exception("Couldn't create process"); } p.EnableRaisingEvents = true; p.OutputDataReceived += (s, e) => buildPane.OutputString(e.Data + "\n"); p.ErrorDataReceived += (s, e) => buildPane.OutputString(e.Data + "\n"); p.Exited += (s, e) => { if (!p.HasExited) { throw new Exception("Tundra process should've exited already!"); } if (p.ExitCode == 0) { buildPane.OutputString(string.Format("========== {0}: {1} succeeded ==========\n", task, projectCount)); } else { buildPane.OutputString(string.Format("========== {0}: Failed: {1} ==========\n", task, p.ExitCode)); } p.Dispose(); }; buildPane.Clear(); buildPane.OutputString(string.Format("------ {0} started: Project{1}: {2}, Configuration: {3} ------\n", task, projectCount != 1 ? "(s)" : "", projects, config)); buildPane.Activate(); Package.DTE.ToolWindows.OutputWindow.Parent.Activate(); p.Start(); p.BeginOutputReadLine(); p.BeginErrorReadLine(); } catch (Exception ex) { messagePane.OutputString(string.Format("Failed to launch Tundra: {0}\n", ex.Message)); } } else { regularCommand = true; } } else { regularCommand = true; } if (regularCommand) { string command = string.Empty; switch (task) { case BuildTask.Compile: command = "Build.Compile"; break; case BuildTask.Build: command = "Build.BuildSolution"; break; case BuildTask.Rebuild: command = "Build.RebuildSolution"; break; case BuildTask.Clean: command = "Build.CleanSolution"; break; } if (!string.IsNullOrEmpty(command)) { Package.DTE.ExecuteCommand(command); } } } catch (Exception ex) { messagePane.OutputString(string.Format("Failed with exception: {0}\n", ex.Message)); messagePane.OutputString(string.Format("{0}\n", ex.StackTrace)); } }
public void Build_Executable() { // Register the test process manager var processManager = new MockProcessManager(); // Register the test listener var testListener = new TestTraceListener(); using (var scopedTraceListener = new ScopedTraceListenerRegister(testListener)) using (var scopedProcesManager = new ScopedSingleton <IProcessManager>(processManager)) { // Setup the input build state var buildState = new MockBuildState(); var state = buildState.ActiveState; // Setup build table var buildTable = new ValueTable(); state.Add("Build", new Value(buildTable)); buildTable.Add("TargetName", new Value("Program")); buildTable.Add("TargetType", new Value((long)BuildTargetType.Executable)); buildTable.Add("SourceRootDirectory", new Value("C:/source/")); buildTable.Add("TargetRootDirectory", new Value("C:/target/")); buildTable.Add("ObjectDirectory", new Value("obj/")); buildTable.Add("BinaryDirectory", new Value("bin/")); buildTable.Add( "Source", new Value(new ValueList() { new Value("TestFile.cs"), })); // Setup parameters table var parametersTable = new ValueTable(); state.Add("Parameters", new Value(parametersTable)); parametersTable.Add("Architecture", new Value("x64")); parametersTable.Add("Compiler", new Value("MOCK")); // Register the mock compiler var compiler = new Compiler.Mock.Compiler(); var compilerFactory = new Dictionary <string, Func <IValueTable, ICompiler> >(); compilerFactory.Add("MOCK", (IValueTable state) => { return(compiler); }); var factory = new ValueFactory(); var uut = new BuildTask(buildState, factory, compilerFactory); uut.Execute(); // Verify expected process manager requests Assert.Equal( new List <string>() { "GetCurrentProcessFileName", "GetCurrentProcessFileName", "GetCurrentProcessFileName", }, processManager.GetRequests()); // Verify expected logs Assert.Equal( new List <string>() { "INFO: Build Generate Done" }, testListener.GetMessages()); var expectedCompileArguments = new CompileArguments() { Target = new Path("./bin/Program.mock.dll"), ReferenceTarget = new Path("./bin/ref/Program.mock.dll"), TargetType = LinkTarget.Executable, SourceRootDirectory = new Path("C:/source/"), TargetRootDirectory = new Path("C:/target/"), ObjectDirectory = new Path("obj/"), SourceFiles = new List <Path>() { new Path("TestFile.cs") }, }; // Verify expected compiler calls Assert.Equal( new List <CompileArguments>() { expectedCompileArguments, }, compiler.GetCompileRequests()); // Verify build state var expectedBuildOperations = new List <BuildOperation>() { new BuildOperation( "MakeDir [./obj/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./obj/\"", new List <Path>(), new List <Path>() { new Path("./obj/"), }), new BuildOperation( "MakeDir [./bin/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/\"", new List <Path>(), new List <Path>() { new Path("./bin/"), }), new BuildOperation( "MakeDir [./bin/ref/]", new Path("C:/target/"), new Path("C:/mkdir.exe"), "\"./bin/ref/\"", new List <Path>(), new List <Path>() { new Path("./bin/ref/"), }), new BuildOperation( "MockCompile: 1", new Path("MockWorkingDirectory"), new Path("MockCompiler.exe"), "Arguments", new List <Path>() { new Path("./InputFile.in"), }, new List <Path>() { new Path("./OutputFile.out"), }), new BuildOperation( "WriteFile [./bin/Program.runtimeconfig.json]", new Path("C:/target/"), new Path("./writefile.exe"), @"""./bin/Program.runtimeconfig.json"" ""{ ""runtimeOptions"": { ""tfm"": ""net5.0"", ""framework"": { ""name"": ""Microsoft.NETCore.App"", ""version"": ""5.0.0"" } } }""", new List <Path>(), new List <Path>() { new Path("./bin/Program.runtimeconfig.json"), }), }; Assert.Equal( expectedBuildOperations, buildState.GetBuildOperations()); } }
public void Args_ShouldCreateProperArgs_With_Resources() { string reference = "external.dll"; string outputAssembly = "myapp.dll"; string source = "myfile.cs"; BuildTask build = new BuildTask("", "library").OutputFileTo(outputAssembly).AddResource("Test", "ResName"); build.BuildArgs(); Assert.That(build._argumentBuilder.Build().Trim(), Is.EqualTo(String.Format("/out:\"{0}\" /resource:\"Test\",ResName /target:{1}", outputAssembly, "library", reference, source))); }
public void Args_ShouldCreateProperReferences() { var references = new List<File>(); references.Add(new File("ref1.dll")); references.Add(new File("ref2.dll")); string outputAssembly = "myapp.dll"; string source = "myfile.cs"; FileSet sources = new FileSet().Include(source); BuildTask build = new BuildTask("", "library").OutputFileTo(outputAssembly).AddRefences(references.ToArray()).AddSources(sources); build.BuildArgs(); Assert.That(build._argumentBuilder.Build().Trim(), Is.EqualTo(String.Format("/out:\"{0}\" /target:{1} /reference:\"{2}\" /reference:\"{3}\" \"{4}\"", outputAssembly, "library", references[0], references[1], source))); }
public void build(PrimitiveList primitives) { UI.printDetailed(UI.Module.ACCEL, "KDTree settings"); UI.printDetailed(UI.Module.ACCEL, " * Max Leaf Size: {0}", maxPrims); UI.printDetailed(UI.Module.ACCEL, " * Max Depth: {0}", MAX_DEPTH); UI.printDetailed(UI.Module.ACCEL, " * Traversal cost: {0}", TRAVERSAL_COST); UI.printDetailed(UI.Module.ACCEL, " * Intersect cost: {0}", INTERSECT_COST); UI.printDetailed(UI.Module.ACCEL, " * Empty bonus: {0}", EMPTY_BONUS); UI.printDetailed(UI.Module.ACCEL, " * Dump leaves: {0}", dump ? "enabled" : "disabled"); Timer total = new Timer(); total.start(); primitiveList = primitives; // get the object space bounds bounds = primitives.getWorldBounds(null); int nPrim = primitiveList.getNumPrimitives(), nSplits = 0; BuildTask task = new BuildTask(nPrim); Timer prepare = new Timer(); prepare.start(); for (int i = 0; i < nPrim; i++) { for (int axis = 0; axis < 3; axis++) { float ls = primitiveList.getPrimitiveBound(i, 2 * axis + 0); float rs = primitiveList.getPrimitiveBound(i, 2 * axis + 1); if (ls == rs) { // flat in this dimension task.splits[nSplits] = pack(ls, PLANAR, axis, i); nSplits++; } else { task.splits[nSplits + 0] = pack(ls, OPENED, axis, i); task.splits[nSplits + 1] = pack(rs, CLOSED, axis, i); nSplits += 2; } } } task.n = nSplits; prepare.end(); Timer t = new Timer(); List<int> tempTree = new List<int>(); List<int> tempList = new List<int>(); tempTree.Add(0); tempTree.Add(1); t.start(); // sort it Timer sorting = new Timer(); sorting.start(); radix12(task.splits, task.n); sorting.end(); // build the actual tree BuildStats stats = new BuildStats(); buildTree(bounds.getMinimum().x, bounds.getMaximum().x, bounds.getMinimum().y, bounds.getMaximum().y, bounds.getMinimum().z, bounds.getMaximum().z, task, 1, tempTree, 0, tempList, stats); t.end(); // write out arrays // free some memory task = null; tree = tempTree.ToArray(); tempTree = null; this.primitives = tempList.ToArray(); tempList = null; total.end(); // display some extra info stats.printStats(); UI.printDetailed(UI.Module.ACCEL, " * Node memory: {0}", Memory.SizeOf(tree)); UI.printDetailed(UI.Module.ACCEL, " * Object memory: {0}", Memory.SizeOf(this.primitives)); UI.printDetailed(UI.Module.ACCEL, " * Prepare time: {0}", prepare); UI.printDetailed(UI.Module.ACCEL, " * Sorting time: {0}", sorting); UI.printDetailed(UI.Module.ACCEL, " * Tree creation: {0}", t); UI.printDetailed(UI.Module.ACCEL, " * Build time: {0}", total); if (dump) { try { UI.printInfo(UI.Module.ACCEL, "Dumping mtls to {0}.mtl ...", dumpPrefix); StreamWriter mtlFile = new StreamWriter(dumpPrefix + ".mtl"); int maxN = stats.maxObjects; for (int n = 0; n <= maxN; n++) { float blend = (float)n / (float)maxN; Color nc; if (blend < 0.25) nc = Color.blend(Color.BLUE, Color.GREEN, blend / 0.25f); else if (blend < 0.5) nc = Color.blend(Color.GREEN, Color.YELLOW, (blend - 0.25f) / 0.25f); else if (blend < 0.75) nc = Color.blend(Color.YELLOW, Color.RED, (blend - 0.50f) / 0.25f); else nc = Color.MAGENTA; mtlFile.WriteLine(string.Format("newmtl mtl{0}", n)); float[] rgb = nc.getRGB(); mtlFile.WriteLine("Ka 0.1 0.1 0.1"); mtlFile.WriteLine(string.Format("Kd {0}g {1}g {2}g", rgb[0], rgb[1], rgb[2])); mtlFile.WriteLine("illum 1\n"); } StreamWriter objFile = new StreamWriter(dumpPrefix + ".obj"); UI.printInfo(UI.Module.ACCEL, "Dumping tree to {0}.obj ...", dumpPrefix); dumpObj(0, 0, maxN, new BoundingBox(bounds), objFile, mtlFile); objFile.Close(); mtlFile.Close(); } catch (Exception e) { Console.WriteLine(e); } } }
public void OutputFileTo_ShouldWorkWithBuildArtifact() { string reference = "external.dll"; var outputAssembly = new File("myapp.dll"); string source = "myfile.cs"; FileSet sources = new FileSet().Include(source); BuildTask build = new BuildTask("", "library").OutputFileTo(outputAssembly).AddRefences(reference).AddSources(sources).IncludeDebugSymbols; build.BuildArgs(); Assert.That(build._argumentBuilder.Build().Trim(), Is.EqualTo(String.Format("/out:\"{0}\" /target:{1} /reference:\"{2}\" /debug \"{3}\"", outputAssembly, "library", reference, source))); }
internal WriterContext(BuildTask task, PipelineLogger logger, FileInfo finfo) : base(task, logger, finfo) { }
public void ShouldExecute() { var mock = MockRepository.GenerateStub<IActionExcecutor>(); BuildTask build = new BuildTask(mock,"vbc.exe", "library"); build.InternalExecute(); mock.AssertWasCalled(x=>x.Execute(Arg<Action<Executable>>.Is.Anything)); }
bool ParseSolution(Project solution) { // get the build target to call Target mainBuildTarget = solution.Targets[options.Target.TargetName]; if (mainBuildTarget == null) { currentResults.Result = BuildResultCode.BuildFileError; currentResults.Add(new BuildError(this.solution.FileName, "Target '" + options.Target + "' not supported by solution.")); return(false); } // example of mainBuildTarget: // <Target Name="Build" Condition="'$(CurrentSolutionConfigurationContents)' != ''"> // <CallTarget Targets="Main\ICSharpCode_SharpDevelop;Main\ICSharpCode_Core;Main\StartUp;Tools" RunEachTargetSeparately="true" /> // </Target> List <BuildTask> mainBuildTargetTasks = Linq.ToList(Linq.CastTo <BuildTask>(mainBuildTarget)); if (mainBuildTargetTasks.Count != 1 || mainBuildTargetTasks[0].Name != "CallTarget") { return(InvalidTarget(mainBuildTarget)); } List <Target> solutionTargets = new List <Target>(); foreach (string solutionTargetName in mainBuildTargetTasks[0].GetParameterValue("Targets").Split(';')) { Target target = solution.Targets[solutionTargetName]; if (target != null) { solutionTargets.Add(target); } } // dictionary for fast lookup of ProjectToBuild elements Dictionary <string, ProjectToBuild> projectsToBuildDict = new Dictionary <string, ProjectToBuild>(); // now look through targets that took like this: // <Target Name="Main\ICSharpCode_Core" Condition="'$(CurrentSolutionConfigurationContents)' != ''"> // <MSBuild Projects="Main\Core\Project\ICSharpCode.Core.csproj" Properties="Configuration=Debug; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') " /> // <MSBuild Projects="Main\Core\Project\ICSharpCode.Core.csproj" Properties="Configuration=Release; Platform=AnyCPU; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" Condition=" ('$(Configuration)' == 'Release') and ('$(Platform)' == 'Any CPU') " /> // </Target> // and add those targets to the "projectsToBuild" list. foreach (Target target in solutionTargets) { List <BuildTask> tasks = Linq.ToList(Linq.CastTo <BuildTask>(target)); if (tasks.Count == 0) { return(InvalidTarget(target)); } // find task to run when this target is executed BuildTask bestTask = null; foreach (BuildTask task in tasks) { if (task.Name != "MSBuild") { return(InvalidTarget(target)); } if (MSBuildInternals.EvaluateCondition(solution, task.Condition)) { bestTask = task; } } if (bestTask == null) { LoggingService.Warn("No matching condition for solution target " + target.Name); bestTask = tasks[0]; } // create projectToBuild entry and add it to list and dictionary string projectFileName = Path.Combine(this.solution.Directory, bestTask.GetParameterValue("Projects")); ProjectToBuild projectToBuild = new ProjectToBuild(Path.GetFullPath(projectFileName), bestTask.GetParameterValue("Targets")); // get project configuration and platform from properties section string propertiesString = bestTask.GetParameterValue("Properties"); Match match = Regex.Match(propertiesString, @"\bConfiguration=([^;]+);"); if (match.Success) { projectToBuild.configuration = match.Groups[1].Value; } else { projectToBuild.configuration = parentEngine.Configuration; } match = Regex.Match(propertiesString, @"\bPlatform=([^;]+);"); if (match.Success) { projectToBuild.platform = match.Groups[1].Value; } else { projectToBuild.platform = parentEngine.Platform; if (projectToBuild.platform == "Any CPU") { projectToBuild.platform = "AnyCPU"; } } projectsToBuild.Add(projectToBuild); projectsToBuildDict[target.Name] = projectToBuild; } // now create dependencies between projectsToBuild foreach (Target target in solutionTargets) { ProjectToBuild p1; if (!projectsToBuildDict.TryGetValue(target.Name, out p1)) { continue; } foreach (string dependency in target.DependsOnTargets.Split(';')) { ProjectToBuild p2; if (!projectsToBuildDict.TryGetValue(dependency, out p2)) { continue; } p1.dependencies.Add(p2); } } return(true); }
static IEnumerator BuildWeaverCoreGameRoutine(FileInfo outputPath, BuildTask <BuildOutput> task) { return(BuildXmlProjectRoutine(new FileInfo("Assets\\WeaverCore\\Other Projects~\\WeaverCore.Game\\WeaverCore.Game\\WeaverCore.Game.csproj"), outputPath, task)); }
private void buildTree(float minx, float maxx, float miny, float maxy, float minz, float maxz, BuildTask task, int depth, List <int> tempTree, int offset, List <int> tempList, BuildStats stats) { // get node bounding box extents if (task.numObjects > maxPrims && depth < MAX_DEPTH) { float dx = maxx - minx; float dy = maxy - miny; float dz = maxz - minz; // search for best possible split float bestCost = INTERSECT_COST * task.numObjects; int bestAxis = -1; int bestOffsetStart = -1; int bestOffsetEnd = -1; float bestSplit = 0; bool bestPlanarLeft = false; int bnl = 0, bnr = 0; // inverse area of the bounding box (factor of 2 ommitted) float area = (dx * dy + dy * dz + dz * dx); float ISECT_COST = INTERSECT_COST / area; // setup counts for each axis int[] nl = { 0, 0, 0 }; int[] nr = { task.numObjects, task.numObjects, task.numObjects }; // setup bounds for each axis float[] dp = { dy *dz, dz *dx, dx *dy }; float[] ds = { dy + dz, dz + dx, dx + dy }; float[] nodeMin = { minx, miny, minz }; float[] nodeMax = { maxx, maxy, maxz }; // search for best cost int nSplits = task.n; long[] splits = task.splits; byte[] lrtable = task.leftRightTable; for (int i = 0; i < nSplits;) { // extract current split long ptr = splits[i]; float split = unpackSplit(ptr); int axis = unpackAxis(ptr); // mark current position int currentOffset = i; // count number of primitives start/stopping/lying on the // current plane int pClosed = 0, pPlanar = 0, pOpened = 0; long ptrMasked = (long)((ulong)ptr & (~((ulong)TYPE_MASK) & 0xFFFFFFFFF0000000L)); long ptrClosed = ptrMasked | CLOSED; long ptrPlanar = ptrMasked | PLANAR; long ptrOpened = ptrMasked | OPENED; while (i < nSplits && ((ulong)splits[i] & 0xFFFFFFFFF0000000L) == (ulong)ptrClosed) { int obj = unpackObject(splits[i]); lrtable[(uint)obj >> 2] = 0;//>>> pClosed++; i++; } while (i < nSplits && ((ulong)splits[i] & 0xFFFFFFFFF0000000L) == (ulong)ptrPlanar) { int obj = unpackObject(splits[i]); lrtable[(uint)obj >> 2] = 0;//>>> pPlanar++; i++; } while (i < nSplits && ((ulong)splits[i] & 0xFFFFFFFFF0000000L) == (ulong)ptrOpened) { int obj = unpackObject(splits[i]); lrtable[(uint)obj >> 2] = 0;//>>> pOpened++; i++; } // now we have summed all contributions from this plane nr[axis] -= pPlanar + pClosed; // compute cost if (split >= nodeMin[axis] && split <= nodeMax[axis]) { // left and right surface area (factor of 2 ommitted) float dl = split - nodeMin[axis]; float dr = nodeMax[axis] - split; float lp = dp[axis] + dl * ds[axis]; float rp = dp[axis] + dr * ds[axis]; // planar prims go to smallest cell always bool planarLeft = dl < dr; int numLeft = nl[axis] + (planarLeft ? pPlanar : 0); int numRight = nr[axis] + (planarLeft ? 0 : pPlanar); float eb = ((numLeft == 0 && dl > 0) || (numRight == 0 && dr > 0)) ? EMPTY_BONUS : 0; float cost = TRAVERSAL_COST + ISECT_COST * (1 - eb) * (lp * numLeft + rp * numRight); if (cost < bestCost) { bestCost = cost; bestAxis = axis; bestSplit = split; bestOffsetStart = currentOffset; bestOffsetEnd = i; bnl = numLeft; bnr = numRight; bestPlanarLeft = planarLeft; } } // move objects left nl[axis] += pOpened + pPlanar; } // debug check for correctness of the scan for (int axis = 0; axis < 3; axis++) { int numLeft = nl[axis]; int numRight = nr[axis]; if (numLeft != task.numObjects || numRight != 0) { UI.printError(UI.Module.ACCEL, "Didn't scan full range of objects @depth={0}. Left overs for axis {1}: [L: {2}] [R: {3}]", depth, axis, numLeft, numRight); } } // found best split? if (bestAxis != -1) { // allocate space for child nodes BuildTask taskL = new BuildTask(bnl, task); BuildTask taskR = new BuildTask(bnr, task); int lk = 0, rk = 0; for (int i = 0; i < bestOffsetStart; i++) { long ptr = splits[i]; if (unpackAxis(ptr) == bestAxis) { if (unpackSplitType(ptr) != CLOSED) { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(1 << ((obj & 3) << 1));//>>> lk++; } } } for (int i = bestOffsetStart; i < bestOffsetEnd; i++) { long ptr = splits[i]; Debug.Assert(unpackAxis(ptr) == bestAxis); if (unpackSplitType(ptr) == PLANAR) { if (bestPlanarLeft) { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(1 << ((obj & 3) << 1));//>>> lk++; } else { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(2 << ((obj & 3) << 1));//>>> rk++; } } } for (int i = bestOffsetEnd; i < nSplits; i++) { long ptr = splits[i]; if (unpackAxis(ptr) == bestAxis) { if (unpackSplitType(ptr) != OPENED) { int obj = unpackObject(ptr); lrtable[(uint)obj >> 2] |= (byte)(2 << ((obj & 3) << 1));//>>> rk++; } } } // output new splits while maintaining order long[] splitsL = taskL.splits; long[] splitsR = taskR.splits; int nsl = 0, nsr = 0; for (int i = 0; i < nSplits; i++) { long ptr = splits[i]; int obj = unpackObject(ptr); int idx = (int)((uint)obj >> 2);//>>> int mask = 1 << ((obj & 3) << 1); if ((lrtable[idx] & mask) != 0) { splitsL[nsl] = ptr; nsl++; } if ((lrtable[idx] & (mask << 1)) != 0) { splitsR[nsr] = ptr; nsr++; } } taskL.n = nsl; taskR.n = nsr; // free more memory task.splits = splits = splitsL = splitsR = null; task = null; // allocate child nodes int nextOffset = tempTree.Count; tempTree.Add(0); tempTree.Add(0); tempTree.Add(0); tempTree.Add(0); // create current node tempTree[offset + 0] = (bestAxis << 30) | nextOffset; tempTree[offset + 1] = ByteUtil.floatToRawIntBits(bestSplit); // recurse for child nodes - free object arrays after each step stats.updateInner(); switch (bestAxis) { case 0: buildTree(minx, bestSplit, miny, maxy, minz, maxz, taskL, depth + 1, tempTree, nextOffset, tempList, stats); taskL = null; buildTree(bestSplit, maxx, miny, maxy, minz, maxz, taskR, depth + 1, tempTree, nextOffset + 2, tempList, stats); taskR = null; return; case 1: buildTree(minx, maxx, miny, bestSplit, minz, maxz, taskL, depth + 1, tempTree, nextOffset, tempList, stats); taskL = null; buildTree(minx, maxx, bestSplit, maxy, minz, maxz, taskR, depth + 1, tempTree, nextOffset + 2, tempList, stats); taskR = null; return; case 2: buildTree(minx, maxx, miny, maxy, minz, bestSplit, taskL, depth + 1, tempTree, nextOffset, tempList, stats); taskL = null; buildTree(minx, maxx, miny, maxy, bestSplit, maxz, taskR, depth + 1, tempTree, nextOffset + 2, tempList, stats); taskR = null; return; default: Debug.Assert(false); break; } } } // create leaf node int listOffset = tempList.Count; int n = 0; for (int i = 0; i < task.n; i++) { long ptr = task.splits[i]; if (unpackAxis(ptr) == 0 && unpackSplitType(ptr) != CLOSED) { tempList.Add(unpackObject(ptr)); n++; } } stats.updateLeaf(depth, n); if (n != task.numObjects) { UI.printError(UI.Module.ACCEL, "Error creating leaf node - expecting {0} found {1}", task.numObjects, n); } tempTree[offset + 0] = (3 << 30) | listOffset; tempTree[offset + 1] = task.numObjects; // free some memory task.splits = null; }
public override void Reset() { base.Reset(); BuildTask?.Reset(); }
void AddProjectTargets(Project p, List <TargetInfo> solutionTargets, Dictionary <Guid, ProjectInfo> projectInfos) { foreach (KeyValuePair <Guid, ProjectInfo> projectInfo in projectInfos) { ProjectInfo project = projectInfo.Value; foreach (string buildTarget in buildTargets) { string target_name = GetTargetNameForProject(project.Name, buildTarget); Target target = p.Targets.AddNewTarget(target_name); target.Condition = "'$(CurrentSolutionConfigurationContents)' != ''"; if (project.Dependencies.Count > 0) { StringBuilder dependencies = new StringBuilder(); foreach (ProjectInfo dependentInfo in project.Dependencies.Values) { if (dependencies.Length > 0) { dependencies.Append(";"); } if (IsBuildTargetName(dependentInfo.Name)) { dependencies.Append("Solution:"); } dependencies.Append(dependentInfo.Name); if (buildTarget != "Build") { dependencies.Append(":" + buildTarget); } } target.DependsOnTargets = dependencies.ToString(); } foreach (TargetInfo targetInfo in solutionTargets) { BuildTask task = null; TargetInfo projectTargetInfo; if (!project.TargetMap.TryGetValue(targetInfo, out projectTargetInfo)) { AddWarningForMissingProjectConfiguration(target, targetInfo.Configuration, targetInfo.Platform, project.Name); continue; } if (projectTargetInfo.Build) { task = target.AddNewTask("MSBuild"); task.SetParameterValue("Projects", project.FileName); if (buildTarget != "Build") { task.SetParameterValue("Targets", buildTarget); } task.SetParameterValue("Properties", string.Format("Configuration={0}; Platform={1}; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)", projectTargetInfo.Configuration, projectTargetInfo.Platform)); } else { task = target.AddNewTask("Message"); task.SetParameterValue("Text", string.Format("Project \"{0}\" is disabled for solution configuration \"{1}|{2}\".", project.Name, targetInfo.Configuration, targetInfo.Platform)); } task.Condition = string.Format(" ('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}') ", targetInfo.Configuration, targetInfo.Platform); } } } }
public void Reset() => BuildTask.Reset();
public void UsingCsc_Compiler_Should_Be_VBC() { BuildTask build = new BuildTask("vbc.exe","library"); Assert.That(Path.GetFileName(build.Compiler), Is.EqualTo("vbc.exe")); }
internal ImporterContext(BuildTask task, PipelineLogger logger, FileInfo finfo) : base(task, logger, finfo) { _dependencies = new List <string>(); }
static IEnumerator BuildXmlProjectRoutine(FileInfo xmlProjectFile, FileInfo outputPath, BuildTask <BuildOutput> task) { if (task == null) { task = new BuildTask <BuildOutput>(); } using (var stream = File.OpenRead(xmlProjectFile.FullName)) { using (var reader = XmlReader.Create(stream, new XmlReaderSettings { IgnoreComments = true })) { reader.ReadToFollowing("Project"); reader.ReadToDescendant("PropertyGroup"); reader.ReadToFollowing("PropertyGroup"); reader.ReadToDescendant("OutputPath"); //reader.NodeType == XmlNodeType.Prope //reader.ReadEndElement(); //reader.ReadToFollowing("PropertyGroup"); //reader.ReadToFollowing("OutputPath"); if (outputPath == null) { var foundOutputPath = reader.ReadElementContentAsString(); if (Path.IsPathRooted(foundOutputPath)) { outputPath = new FileInfo(PathUtilities.AddSlash(foundOutputPath) + "WeaverCore.Game.dll"); } else { outputPath = new FileInfo(PathUtilities.AddSlash(xmlProjectFile.Directory.FullName) + PathUtilities.AddSlash(foundOutputPath) + "WeaverCore.Game.dll"); } } //Debug.Log("Output Path = " + foundOutputPath); //reader.ReadEndElement(); reader.ReadToFollowing("ItemGroup"); List <XmlReference> References = new List <XmlReference>(); List <string> Scripts = new List <string>(); while (reader.Read()) { if (reader.Name == "Reference") { var referenceName = reader.GetAttribute("Include"); FileInfo hintPath = null; while (reader.Read() && reader.Name != "Reference") { if (reader.Name == "HintPath") { var contents = reader.ReadElementContentAsString(); if (Path.IsPathRooted(contents)) { hintPath = new FileInfo(contents); } else { hintPath = new FileInfo(PathUtilities.AddSlash(xmlProjectFile.Directory.FullName) + contents); } //reader.ReadEndElement(); } } if (referenceName.Contains("Version=") || referenceName.Contains("Culture=") || referenceName.Contains("PublicKeyToken=") || referenceName.Contains("processorArchitecture=")) { referenceName = new AssemblyName(referenceName).Name; } References.Add(new XmlReference { AssemblyName = referenceName, HintPath = hintPath }); } else if (reader.Name == "ItemGroup") { break; } } foreach (var scriptFile in xmlProjectFile.Directory.GetFiles("*.cs", SearchOption.AllDirectories)) { Scripts.Add(scriptFile.FullName); } /*reader.ReadToFollowing("ItemGroup"); * while (reader.Read() && reader.Name != "ItemGroup") * { * if (reader.Name == "Compile") * { * var contents = reader.GetAttribute("Include"); * if (Path.IsPathRooted(contents)) * { * //Scripts.Add(new FileInfo(contents).FullName); * } * else * { * //Scripts.Add(new FileInfo(PathUtilities.AddSlash(xmlProjectFile.Directory.FullName) + contents).FullName); * } * if (!reader.IsEmptyElement) * { * reader.ReadEndElement(); * } * } * }*/ /*Debug.Log("Results!"); * foreach (var r in References) * { * Debug.Log($"Assembly Name = {r.AssemblyName}, Hint Path = {r.HintPath?.FullName}"); * } * * foreach (var s in Scripts) * { * Debug.Log("Script = " + s); * } * * Debug.Log("Output Path = " + outputPath);*/ /*while (reader.Read()) * { * Debug.Log("Reader Name = " + reader.Name); * Debug.Log("Reader Local Name = " + reader.LocalName); * //reader.IsStartElement() * }*/ List <DirectoryInfo> AssemblySearchDirectories = new List <DirectoryInfo> { new DirectoryInfo(PathUtilities.AddSlash(GameBuildSettings.Settings.HollowKnightLocation) + "hollow_knight_Data\\Managed"), new FileInfo(typeof(UnityEditor.EditorWindow).Assembly.Location).Directory }; /*foreach (var searchDir in AssemblySearchDirectories) * { * Debug.Log("Search Directory = " + searchDir.FullName); * }*/ List <string> AssemblyReferences = new List <string>(); foreach (var xmlRef in References) { /*if (xmlRef.AssemblyName.Contains("UnityEngine")) * { * continue; * }*/ if (xmlRef.AssemblyName == "System") { continue; } if (xmlRef.HintPath != null && xmlRef.HintPath.Exists) { AssemblyReferences.Add(xmlRef.HintPath.FullName); } else { bool found = false; foreach (var searchDir in AssemblySearchDirectories) { var filePath = PathUtilities.AddSlash(searchDir.FullName) + xmlRef.AssemblyName + ".dll"; //Debug.Log("File Path = " + filePath); if (File.Exists(filePath)) { found = true; AssemblyReferences.Add(filePath); break; } } if (!found) { Debug.LogError("Unable to find WeaverCore.Game Reference -> " + xmlRef.AssemblyName); } } } var scriptAssemblies = new DirectoryInfo("Library\\ScriptAssemblies").GetFiles("*.dll"); List <string> exclusions = new List <string>(); foreach (var sa in scriptAssemblies) { exclusions.Add(PathUtilities.ConvertToProjectPath(sa.FullName)); //Debug.Log("Exclusion = " + exclusions[exclusions.Count - 1]); } var weaverCoreLibraries = new DirectoryInfo("Assets\\WeaverCore\\Libraries").GetFiles("*.dll"); foreach (var wl in weaverCoreLibraries) { exclusions.Add(PathUtilities.ConvertToProjectPath(wl.FullName)); } var editorDir = new FileInfo(typeof(UnityEditor.EditorWindow).Assembly.Location).Directory; foreach (var ueFile in editorDir.Parent.GetFiles("UnityEngine.dll", SearchOption.AllDirectories)) { exclusions.Add(ueFile.FullName); } //var editorUnityEngineDll = new FileInfo(PathUtilities.AddSlash(editorDir.Parent.FullName) + "UnityEngine.dll"); //Debug.Log("Editor Unity Engine Location = " + editorUnityEngineDll); //exclusions.Add(editorUnityEngineDll.FullName); //Debug.Log("Editor Location = " + ); //Debug.Log("System Location = " + typeof(System.Array).Assembly.Location); //exclusions.Add("Library\\ScriptAssemblies\\HollowKnight.dll"); yield return(BuildAssembly(new BuildParameters { BuildPath = outputPath, Scripts = Scripts, Defines = new List <string> { "GAME_BUILD" }, ExcludedReferences = exclusions, AssemblyReferences = AssemblyReferences, }, BuildPresetType.None, task)); } } yield break; }
protected override void OnTaskDone(BuildTask buildTask) { }
public async Task RunJob(BuildTaskBase?buildTaskBase) { await SetupWorkspace(); logger.LogTrace("Copied workspace"); Directory.CreateDirectory(ArtifactDir); var psi = buildTaskBase switch { BuildTask buildTask => CreateBuildProcess(buildDir, buildTask), ContainerBuildTask containerBuildTask => CreateContainerBuildProcess(buildDir, containerBuildTask), _ => throw new Exception("Invalid build task") }; cancellationToken.ThrowIfCancellationRequested(); var process = Process.Start(psi); logger.LogTrace("Running external process"); var exitTask = process.WaitForExitAsync(); var writerLock = new AsyncLock(); async Task PipeData(Stream stream) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0) { cancellationToken.ThrowIfCancellationRequested(); using (await writerLock.LockAsync()) { cancellationToken.ThrowIfCancellationRequested(); await updateStream.WriteAsync(new BuildStatusUpdate { BuildOutput = ByteString.CopyFrom(buffer.AsSpan(0, bytesRead)), }); } cancellationToken.ThrowIfCancellationRequested(); } stream.Close(); } var outputTask = Task.Run(() => PipeData(process.StandardOutput.BaseStream), cancellationToken); var errorTask = Task.Run(() => PipeData(process.StandardError.BaseStream), cancellationToken); await Task.WhenAll(outputTask, errorTask, exitTask); var artifactDir = ArtifactDir; var artifacts = Directory.EnumerateFiles(artifactDir, "*.json", SearchOption.AllDirectories) .Select(file => new ArtifactInfo { Name = file.Substring(artifactDir.Length) .TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) }); var jobResult = new JobResult { ExitCode = process.ExitCode, }; jobResult.Artifacts.AddRange(artifacts); await updateStream.WriteAsync(new BuildStatusUpdate { JobFinished = jobResult, }); logger.LogTrace("Finished job"); }
public HandlerAsync(BuildTask task) { this.task = task; }
public void StartBuild(TreeNodeCollection nodes) { BuildTask task = new BuildTask(this, nodes, TIA); thread.RunAsync(task); }