private void BtnAddcheck_Click(object sender, RoutedEventArgs e) { ScanImportFolders frm = new ScanImportFolders(); frm.Owner = GetTopParent(); bool? result = frm.ShowDialog(); if (result.HasValue && result.Value) { this.IsEnabled = false; Cursor = Cursors.Wait; Scan s = frm.SelectedScan; HashSet<int> imp=new HashSet<int>(s.ImportFolderList); List<VideoLocal> vl=imp.SelectMany(a=>RepoFactory.VideoLocal.GetByImportFolder(a)).Distinct().ToList(); List<ScanFile> files=new List<ScanFile>(); foreach (VideoLocal v in vl) { foreach (VideoLocal_Place p in v.Places.Where(a => imp.Contains(a.ImportFolderID))) { ScanFile sfile=new ScanFile(); sfile.Hash = v.ED2KHash; sfile.FileSize = v.FileSize; sfile.FullName = p.FullServerPath; sfile.ScanID = s.ScanID; sfile.Status = (int) ScanFileStatus.Waiting; sfile.ImportFolderID = p.ImportFolderID; sfile.VideoLocal_Place_ID = p.VideoLocal_Place_ID; files.Add(sfile); } } RepoFactory.ScanFile.Save(files); this.IsEnabled = true; Scanner.Instance.Scans.Add(s); comboProvider.SelectedItem = s; Cursor = Cursors.Arrow; } }
private static IEnumerable<CompAir> ContiguousAirBuildings( Building root, NetLayer layer ) { closedSet.Clear(); currentSet.Clear(); openSet.Add( root ); do { //Move all opened to closed foreach (var current in openSet) { closedSet.Add( current ); } var tempSet = currentSet; currentSet = openSet; openSet = tempSet; openSet.Clear(); foreach (var things in currentSet.SelectMany( openBuilding => GenAdj.CellsAdjacentCardinal( openBuilding ) .Select( openCells => openCells.GetThingList() ) ) ) { //All adjacent things foreach (var current in things) { var building = current as Building; var compAir = building?.TryGetComp< CompAir >(); //No adjacent CompAir if (compAir == null) { continue; } //CompAir is not on the same layer if (!compAir.IsLayerOf( layer )) { continue; } //Already swept through if (openSet.Contains( building ) || currentSet.Contains( building ) || closedSet.Contains( building )) { continue; } openSet.Add( building ); break; } } } while (openSet.Count > 0); return from b in closedSet select b.TryGetComp< CompAir >(); }
public static int Solve(string[] input, int dimentions) { var activeCells = new HashSet <Vec>(); var y = 0; foreach (var row in input) { for (var x = 0; x < row.Length; x++) { if (row[x] == '#') { var coordinates = new int[dimentions]; coordinates[0] = x; coordinates[1] = y; activeCells.Add(new Vec(coordinates)); } } y++; } var nVectors = new Vec(new int[dimentions]).GetNeighbours(); for (int i = 0; i < 6; i++) { var activeCells2 = activeCells.ToHashSet(); var cells = activeCells.Concat(activeCells.SelectMany(x => nVectors.Select(nv => nv.Add(x)))).ToHashSet(); foreach (var c in cells) { var activeNeighbours = nVectors.Select(nv => nv.Add(c)).Count(n => activeCells.Contains(n)); if (activeCells.Contains(c)) { if (activeNeighbours < 2 || activeNeighbours > 3) { activeCells2.Remove(c); } } else { if (activeNeighbours == 3) { activeCells2.Add(c); } } } activeCells = activeCells2; } return(activeCells.Count); }
public ValidationResult Validate(IValidationContext context) { var validationResults = new HashSet <ValidationResult>(); foreach (var validator in _validators) { var res = validator.Validate(context); validationResults.Add(res); } return(new ValidationResult(validationResults.SelectMany(vr => vr.Errors))); }
public static ILspHandlerTypeDescriptor GetHandlerTypeForRegistrationOptions(object registrationOptions) { var registrationType = registrationOptions.GetType(); var interfaces = new HashSet <Type>(registrationOptions.GetType().GetInterfaces() .Except(registrationType.BaseType?.GetInterfaces() ?? Enumerable.Empty <Type>())); return(interfaces.SelectMany(x => KnownHandlers.Values .Where(z => z.HasRegistration) .Where(z => x.IsAssignableFrom(z.RegistrationType))) .FirstOrDefault()); }
private Player TerritoryOwner(HashSet <Point> coords) { var neighborColors = coords.SelectMany(NonEmptyNeighborCoordinates).Where(isTaken).Select(GetPlayer); var uniqueNeighborColors = ToSet(neighborColors); if (uniqueNeighborColors.Count == 1) { return(uniqueNeighborColors.First()); } return(Player.None); }
/// <summary> /// Searches entries in the current table and enumerates every single distinct class found. /// </summary> /// <returns></returns> public IEnumerable <string> GetClasses() { var lstClasses = new HashSet <string>(); foreach (string c in _entriesHash.SelectMany(e => e.GetClasses())) { if (lstClasses.Add(c)) { yield return(c); } } }
private IRequestDescriptor <ILspHandlerDescriptor> FindDescriptor(string method, JToken? @params) { _logger.LogDebug("Finding descriptors for {Method}", method); var descriptor = _collection.FirstOrDefault(x => x.Method == method); if (descriptor is null) { _logger.LogDebug( "Unable to find {Method}, methods found include {Methods}", method, string.Join(", ", _collection.Select(x => x.Method + ":" + x.Handler.GetType().FullName)) ); return(new RequestDescriptor <ILspHandlerDescriptor>()); } if (@params == null || descriptor.Params == null) { return(new RequestDescriptor <ILspHandlerDescriptor>(descriptor)); } object?paramsValue; if (descriptor.IsDelegatingHandler) { var o = @params.ToObject(descriptor.Params.GetGenericArguments()[0], _serializer.JsonSerializer); paramsValue = Activator.CreateInstance(descriptor.Params, o); } else { paramsValue = @params.ToObject(descriptor.Params, _serializer.JsonSerializer); } var lspHandlerDescriptors = _collection.Where(handler => handler.Method == method).ToList(); var matchDescriptor = _handlerMatchers.SelectMany(strat => strat.FindHandler(paramsValue, lspHandlerDescriptors)).ToArray(); if (matchDescriptor.Length > 0) { return(new RequestDescriptor <ILspHandlerDescriptor>(matchDescriptor)); } // execute command is a special case // if no command was found to execute this must error // this is not great coupling but other options require api changes if (paramsValue is IExecuteCommandParams) { return(new RequestDescriptor <ILspHandlerDescriptor>()); } if (lspHandlerDescriptors.Count > 0) { return(new RequestDescriptor <ILspHandlerDescriptor>(lspHandlerDescriptors)); } return(new RequestDescriptor <ILspHandlerDescriptor>()); }
public static void Run() { var input = File .ReadAllLines("../../../input/09.txt") .SelectMany((l, y) => l.Select((c, x) => (new Point(x, y), int.Parse(c.ToString())))) .ToDictionary(l => l.Item1, l => l.Item2); var neighbors = new List <Point>() { new Point(-1, 0), new Point(1, 0), new Point(0, -1), new Point(0, 1) }; var lowPoints = input .Where(l => neighbors .Select(p => p + l.Key) .Where(input.ContainsKey) .All(p => input[p] > l.Value)) .ToList();; lowPoints .Sum(l => l.Value + 1) .Dump("09a (594): "); lowPoints.Select(l => Area(l.Key)) .OrderByDescending(x => x) .Take(3) .Aggregate(1, (a, x) => a * x) .Dump("09b (858494): "); int Area(Point p) { var ps = new HashSet <Point> { p }; var ns = new HashSet <Point>(); do { ps = ps.Union(ns).ToHashSet(); ns = ps.SelectMany(x => neighbors .Select(n => n + x) .Where(input.ContainsKey) .Where(x => input[x] != 9)) .ToHashSet(); } while (ps.Union(ns).Count() > ps.Count); return(ps.Count); }; }
private IEnumerable <Type> GetBaseImplementorsPerHierarchy(Type ancestor) { IEnumerable <Type> implementorsPerEachDomainClass = explicitDeclarations.DomainClasses.Select(type => type.GetFirstImplementorOf(ancestor)).Where(implementor => implementor != null && !IsExplicitlyExcluded(implementor)); var implementorsPerEachDomainClassSet = new HashSet <Type>(implementorsPerEachDomainClass); var inherited = implementorsPerEachDomainClassSet.SelectMany(implementor => implementorsPerEachDomainClassSet.Where(t => !t.Equals(implementor) && implementor.IsAssignableFrom(t))).ToArray(); implementorsPerEachDomainClassSet.ExceptWith(inherited); return(implementorsPerEachDomainClassSet); }
// public HashSet<string> Prefixes(string word) // { // return word.Prefixes; // var result = new HashSet<string>(); // for (var i = 0; i < word.Length; i++) // { // result.Add(word.Substring(0, i)); // } // return result; // } public Tuple <HashSet <string>, HashSet <string> > ReadWordList(string filename) { var wordset = new HashSet <string>( new StreamReader(File.OpenRead("words4k.txt")).ReadToEnd().ToUpper().Split("\r\n".ToCharArray()). Where(s => !string.IsNullOrEmpty(s))); var prefixes = wordset.SelectMany((w) => { return(w.Prefixes()); }); var prefixset = new HashSet <string>(); return(new Tuple <HashSet <string>, HashSet <string> >(wordset, prefixset)); }
private void Update() { if (HasEnergy) { var lines = connectedPlayers.SelectMany(p => new[] { transform.position, p.transform.position, transform.position }).ToArray(); lineRenderer.positionCount = lines.Length; lineRenderer.SetPositions(lines); } else { lineRenderer.positionCount = 0; } }
/// <summary> /// This will delete the entity from model dictionary and also from any references in the model. /// Be carefull as this might take a while to check for all occurances of the object. Also make sure /// you don't use this object anymore yourself because it won't get disposed until than. This operation /// doesn't guarantee that model is compliant with any kind of schema but it leaves it consistent. So if you /// serialize the model there won't be any references to the object which wouldn't be there. /// </summary> /// <param name="model">Model from which the entity should be deleted</param> /// <param name="entities">Entities to be deleted</param> /// <param name="instanceRemoval">Delegate to be used to remove entity from instance collection. /// This should be reversable action within a transaction.</param> public static void Delete(IModel model, IPersistEntity[] entities, Action <IPersistEntity[]> instanceRemoval) { var uniqueTypes = new HashSet <Type>(entities.Select(e => e.GetType())); var referingTypes = new HashSet <ReferingType>(uniqueTypes.SelectMany(t => GetReferingTypes(model, t))); foreach (var referingType in referingTypes) { ReplaceReferences <IPersistEntity, IPersistEntity>(model, entities, referingType, null); } //Remove from entity collection. This must be at the end for case it is being used in the meantime. instanceRemoval(entities); }
public static HashSet <List <byte> > Permute(HashSet <byte> input) => input.Count > 1 ? input.SelectMany(b => { var subs = Permute(input.Except(new [] { b }).ToHashSet()); return(subs.Select(l => { l.Insert(0, b); return l; })); }).ToHashSet() : new HashSet <List <byte> > { input.ToList() };
public void GarbageCollect(bool removeUnusedBehaviors, HashSet <string> usedBrainIds) { brains.DeleteAll(brains.ComplementOf(usedBrainIds).ToList()); if (removeUnusedBehaviors) { HashSet <string> usedEmbeddedBehaviors = new HashSet <string>( usedBrainIds.SelectMany(brainId => GetBrain(brainId).behaviorUses.Select(use => use.behaviorUri)). Where(uri => BehaviorSystem.IsEmbeddedBehaviorUri(uri)). Select(uri => BehaviorSystem.GetIdOfBehaviorUri(uri))); behaviors.DeleteAll(behaviors.ComplementOf(usedEmbeddedBehaviors).ToList()); } }
// Gets the neighbours of a face which are within radius steps of it. private IEnumerable <Face> GetNearbyFaces(Face center, int radius) { var faces = new HashSet <Face> { center }; for (int i = 1; i < radius; i++) { var neighbours = faces.SelectMany(face => _polyhedron.NeighboursOf(face)).ToList(); faces.UnionWith(neighbours); } return(faces); }
private SolutionSpec GenerateSolution() { var dict = new Dictionary <Vector, int>(); var points = UsedPolygons.SelectMany(p => p.Vertices).Distinct().ToArray(); for (int i = 0; i < points.Length; i++) { dict[points[i]] = i; } var facets = UsedPolygons.Select(polygon => new Facet(polygon.Vertices.Select(v => dict[v]).ToArray())).ToArray(); var dest = points.Select(GetDestVector).ToArray(); return(new SolutionSpec(points, facets, dest)); }
public void RemoveTips() { Console.WriteLine("Removing tips..."); var frontTips = _graph .Except(_graph .SelectMany(n => n.Neighbors)) .Where(n => n.Neighbors.Count == 1); var frontTipsToRemove = new HashSet <Node>(); foreach (var frontTip in frontTips) { if (frontTipsToRemove.Contains(frontTip)) { continue; } var neighbor = frontTip.Neighbors.Single(); var nodesWithSameNeighbor = _graph .Where(n => n.Neighbors.Contains(neighbor)) .Where(n => n.Neighbors.Count == 1) .OrderByDescending(n => n.Weights.Single()); foreach (var n in nodesWithSameNeighbor) { frontTipsToRemove.Add(n); } } foreach (var tip in frontTipsToRemove.Distinct()) { RemoveFrontTip(tip); } Console.WriteLine($"Removed {frontTipsToRemove.Count()} tips..."); }
public static IEnumerable <IGraphElementModel> DeleteElements(this IGraphModel self, IReadOnlyCollection <IGraphElementModel> graphElementModels) { var stickyNoteModels = new HashSet <IStickyNoteModel>(); var placematModels = new HashSet <IPlacematModel>(); var variableDeclarationsModels = new HashSet <IVariableDeclarationModel>(); var edgeModels = new HashSet <IEdgeModel>(); var nodeModels = new HashSet <INodeModel>(); foreach (var element in graphElementModels) { switch (element) { case IStickyNoteModel stickyNoteModel: stickyNoteModels.Add(stickyNoteModel); break; case IPlacematModel placematModel: placematModels.Add(placematModel); break; case IVariableDeclarationModel variableDeclarationModel: variableDeclarationsModels.Add(variableDeclarationModel); break; case IEdgeModel edgeModel: edgeModels.Add(edgeModel); break; case INodeModel nodeModel: nodeModels.Add(nodeModel); break; } } // Add nodes that would be backed by declaration models. nodeModels.AddRangeInternal(variableDeclarationsModels.SelectMany(d => self.FindReferencesInGraph <IHasDeclarationModel>(d).OfType <INodeModel>())); // Add edges connected to the deleted nodes. foreach (var portModel in nodeModels.OfType <IPortNodeModel>().SelectMany(n => n.Ports)) { edgeModels.AddRangeInternal(self.EdgeModels.Where(e => e.ToPort == portModel || e.FromPort == portModel)); } return(self.DeleteStickyNotes(stickyNoteModels) .Concat(self.DeletePlacemats(placematModels)) .Concat(self.DeleteEdges(edgeModels)) .Concat(self.DeleteVariableDeclarations(variableDeclarationsModels, deleteUsages: false)) .Concat(self.DeleteNodes(nodeModels, deleteConnections: false)).ToList()); }
static void Prim() { //initialize priority queue and its comparer with sorted rules var queue = new OrderedBag <Edge>(Comparer <Edge> .Create((a, b) => a.Cost - b.Cost)); //all alredy connected nodes -> add their childs in priority queue queue.AddMany(spanningTree.SelectMany(x => graph[x])); //while priority queue is not empty while (queue.Count > 0) { //get smallest edge by cost var min = queue.RemoveFirst(); //check if min node connects tree node with non tree node var nonTreeNode = -1; if (spanningTree.Contains(min.First) && !spanningTree.Contains(min.Second)) //first case { nonTreeNode = min.Second; } if (spanningTree.Contains(min.Second) && !spanningTree.Contains(min.First)) //second case { nonTreeNode = min.First; } //no need of this edge because if connects two tree nodes(already connected) or two non tree nodes (non node of this edge is not connected to existing network) if (nonTreeNode == -1) { continue; } //check if cost of new edge to be connected fit in budget if (budget >= min.Cost) { budget -= min.Cost; usedBudget += min.Cost; } else { break; } //add nonTree node to already existing network spanningTree.Add(nonTreeNode); //add its child edges to priority queue queue.AddMany(graph[nonTreeNode]); } }
private static int DistanceToTerrs(BotMain bot, TerritoryIDType startFrom, HashSet <TerritoryIDType> terrs, GameStanding standing, int maxDistance, out HashSet <TerritoryIDType> terrsWeEntered) { Assert.Fatal(terrs.Count > 0, "No terrs"); var visited = new HashSet <TerritoryIDType>(); visited.Add(startFrom); var contains = visited.Where(o => terrs.Contains(o)).ToHashSet(true); if (contains.Count > 0) { //We're already there terrsWeEntered = new HashSet <TerritoryIDType>(); return(0); } int distance = 1; while (true) { var expand = visited.SelectMany(o => bot.Map.Territories[o].ConnectedTo.Keys).Where(o => visited.Contains(o) == false && standing.Territories[o].OwnerPlayerID != bot.PlayerID).ToHashSet(false); if (expand.Count == 0) { terrsWeEntered = null; return(int.MaxValue); } contains = expand.Where(o => terrs.Contains(o)).ToHashSet(true); if (contains.Count > 0) { //Found it terrsWeEntered = contains; return(distance); } distance++; if (distance > maxDistance) { terrsWeEntered = null; return(int.MaxValue); } visited.AddRange(expand); } #if CS2HX || CSSCALA throw new Exception("Never"); #endif }
public static IList <Settlement> Evolve(IEnumerable <Settlement> settlements) { var oldWorld = new HashSet <Settlement>(settlements); var settlementAndNeighbourCounts = oldWorld.SelectMany(Evolution.GenerateNeighbours) .GroupBy(s => new { s.X, s.Y }) .Select(gs => new { Settlement = new Settlement(gs.Key.X, gs.Key.Y), NeighbourCount = gs.Count() }); var evolution = settlementAndNeighbourCounts.Where(sn => sn.NeighbourCount == 3 || (sn.NeighbourCount == 2 && oldWorld.Contains(sn.Settlement))) .Select(sn => new Settlement(sn.Settlement.X, sn.Settlement.Y)) .ToList(); return(evolution); }
private Rectangle TryInsert(Size size) { var rect = spots .SelectMany(w => new [] { Rectangle.FromLeftBottom(w, size), Rectangle.FromRightBottom(w, size), Rectangle.FromLeftTop(w, size), Rectangle.FromRightTop(w, size), }) .Where(r => !IsIntersected(r)).ToList() .MinOrDefault(Aberration); return(rect); }
private static ISet <Type> GetUsedModelsFrom(ApiDescription api) { // Para cada tipo: // - Se primitivo (simples) remover // - Se Lista Obter tipo // - Para cada propriedade do tipo, fazer o mesmo. var parameters = new HashSet <Type>(api.ParameterDescriptions.Select(a => a.ParameterDescriptor.ParameterType)); var returnType = GetReturnType(api); if (returnType != null) { parameters.Add(returnType); } return(new HashSet <Type>(parameters.SelectMany(a => GetNestedUsedModels(a, new HashSet <Type>())))); }
public HashSet <TagViewModel> AddOrUpdateTags(string filePath, HashSet <TagViewModel> tags) { tags.UnionWith(this.GetTags(filePath)); var tagListStrings = tags.SelectMany(x => x.Name).Distinct(); var url = NSUrl.CreateFileUrl(new string[] { filePath }); var tagList = new NSMutableArray(); foreach (var tag in tagListStrings) { tagList.Add(new NSString(tag)); } url.SetResource(new NSString("NSURLTagNamesKey"), tagList); return(tags); }
public override void AfterAllTransforms([NotNull] GlobalContext globalContext, [NotNull] ConfigureOptions configureOptions, [NotNull] TransformOptions transformOptions) { foreach (var kvp in _matchesByGroup.OrderBy(kvp => kvp.Key)) { Log.WriteInfo($"Checked {kvp.Value} dependencies matching group {kvp.Key}"); } foreach (var r in _allCheckedGroups.SelectMany(g => g.AllRules) .Select(r => r.Source) .Distinct() .OrderBy(r => r.RuleSourceName) .ThenBy(r => r.LineNo)) { if (transformOptions.ShowUnusedQuestionableRules && r.IsQuestionableRule && !r.WasHit) { Log.WriteInfo("Questionable rule " + r + " was never matched - maybe you can remove it!"); } else if (transformOptions.ShowUnusedRules && !r.WasHit) { Log.WriteInfo("Rule " + r + " was never matched - maybe you can remove it!"); } else { if (Log.IsChattyEnabled) { Log.WriteInfo("Rule " + r + " was hit " + r.HitCount + " times."); } } } if (_allFilesCt == 1) { Log.WriteInfo(_okFilesCt == 1 ? "Input file is without violations." : "Input file has violations."); } else if (_okFilesCt == _allFilesCt) { Log.WriteInfo($"All {_okFilesCt} input files are without violations."); } else if (_okFilesCt == 0) { Log.WriteInfo($"All {_allFilesCt} input files have violations."); } else { Log.WriteInfo($"{_allFilesCt - _okFilesCt} input files have violations, {_okFilesCt} are without violations."); } }
private Dictionary <TerritoryIDType, PossibleExpandTarget> GetExpansionWeights(HashSet <TerritoryIDType> terrs) { var bonusPaths = terrs .SelectMany(o => Bot.Map.Territories[o].PartOfBonuses) .Where(o => Bot.BonusValue(o) > 0) .Distinct() .Select(o => { if (Bot.PastTime(7)) { return(null); //stop trying to expand if we're slow } return(BonusPath.TryCreate(Bot, o, ts => ts.OwnerPlayerID == Bot.PlayerID)); }) .Where(o => o != null) .ToDictionary(o => o.BonusID, o => o); var turnsToTake = bonusPaths.Keys.ToDictionary(o => o, o => TurnsToTake(o, bonusPaths[o])); foreach (var cannotTake in turnsToTake.Where(o => o.Value == null).ToList()) { turnsToTake.Remove(cannotTake.Key); bonusPaths.Remove(cannotTake.Key); } var bonusWeights = bonusPaths.Keys.ToDictionary(o => o, o => ExpansionHelper.WeighBonus(Bot, o, ts => ts.OwnerPlayerID == Bot.PlayerID, turnsToTake[o].NumTurns)); AILog.Log("Expand", "GetExpansionWeights called with " + terrs.Count + " territories. Weighted " + bonusWeights.Count + " bonuses:"); foreach (var bw in bonusWeights.OrderByDescending(o => o.Value).Take(10)) { AILog.Log("Expand", " - " + Bot.BonusString(bw.Key) + " Weight=" + bw.Value + " " + turnsToTake[bw.Key] + " TurnsToTakeByDistance=" + bonusPaths[bw.Key].TurnsToTakeByDistance + " CriticalPath=" + bonusPaths[bw.Key].TerritoriesOnCriticalPath.Select(o => Bot.TerrString(o)).JoinStrings(", ")); } var ret = new Dictionary <TerritoryIDType, PossibleExpandTarget>(); foreach (var terr in terrs) { ret[terr] = new PossibleExpandTarget(Bot, terr, Bot.Map.Territories[terr].PartOfBonuses.Where(b => bonusPaths.ContainsKey(b)).ToDictionary(b => b, b => new PossibleExpandTargetBonus(bonusWeights[b], bonusPaths[b], turnsToTake[b]))); } AILog.Log("Expand", "Finished weighing " + terrs.Count + " territories:"); foreach (var terr in ret.OrderByDescending(o => o.Value.Weight).Take(10)) { AILog.Log("Expand", " - " + Bot.TerrString(terr.Key) + " Weight=" + terr.Value); } return(ret); }
/// <summary> /// Check if the merged mesh is closed by verifying that all its edges have a corresponding reversed edge. /// </summary> /// <returns>Boolean value that indicates whether the merged mesh is closed or not</returns> public bool IsClosed() { // All edges should have at least one corresponding reversed edge for the mesh to be closed if (_mergedFaceList.Count == 0) { throw new InvalidOperationException("IsClosed called before coplanar triangle merge"); } // This isn't the most optimized approach, but it's intended to be used only after merging // Meshes as those don't have any API data that indicates whether they are closed or not. // Ideally we'd want to have an appropriate API method in the future, or use a better mesh // structure for analysis, like a proper half-edge representation. IEnumerable <IndexSegment> edges = _mergedFaceList.SelectMany(x => facesColl[x].outerAndInnerBoundaries); return(edges.Select(x => x.reverse()).All(x => edges.Any(y => x.coincide(y, false)))); }
public void Test_PutRectanglesWithoutIntersections() { var random = new Random(0); var rectangles = new HashSet <Rectangle>(); for (var i = 0; i < 50; i++) { rectangles.Add(cloud.PutNextRectangle(new Size(random.Next(1, 10), random.Next(1, 10)))); } var intersections = rectangles.SelectMany(r => rectangles. Where(rec => rec != r). Select(rec => Tuple.Create(r, rec))) .Select(t => t.Item1.IntersectsWith(t.Item2)); Assert.IsFalse(intersections.Any(t => t)); }
private HashSet <Tuple <int, int> > TerritoryHelper(HashSet <Tuple <int, int> > remainder, HashSet <Tuple <int, int> > acc) { if (!remainder.Any()) { return(acc); } var emptyNeighbors = new HashSet <Tuple <int, int> >(remainder.SelectMany(EmptyNeighborCoordinates)); emptyNeighbors.ExceptWith(acc); var newAcc = ToSet(acc); newAcc.UnionWith(emptyNeighbors); return(TerritoryHelper(emptyNeighbors, newAcc)); }
static public string[] GetAllFileNames() { // We can't assume where all of the sequence file types will exist, so to provide // this functionality we will have to do the following: // Iterate all of the sequence type descriptors and build a set of file types. HashSet <string> fileTypes = new HashSet <string>(); IEnumerable <ISequenceModuleDescriptor> sequenceDescriptors = Modules.GetDescriptors <ISequenceModuleInstance, ISequenceModuleDescriptor>(); foreach (ISequenceModuleDescriptor descriptor in sequenceDescriptors) { fileTypes.Add(descriptor.FileExtension); } // Find all files of those types in the data branch. return(fileTypes.SelectMany(x => System.IO.Directory.GetFiles(Paths.DataRootPath, "*" + x, SearchOption.AllDirectories)).ToArray()); }
/* * Checks if region contains alphabet elements only */ public bool IsValidRegion(HashSet <PuzzleCell <int> > region) { var regionValues = region.SelectMany(x => x.Items).ToArray(); var alphabetValues = PuzzleAlphabet.GetAllElements(); //sort array before comparing them Array.Sort(alphabetValues); Array.Sort(regionValues); if (!regionValues.SequenceEqual(alphabetValues)) { return(false); } return(true); }
public string[] GetAllSequenceFileNames() { // We can't assume where all of the sequence file types will exist, so to provide // this functionality we will have to do the following: // Iterate all of the sequence type descriptors and build a set of file types. HashSet<string> fileTypes = new HashSet<string>(); IEnumerable<ISequenceTypeModuleDescriptor> sequenceDescriptors = Modules.GetDescriptors<ISequenceTypeModuleInstance, ISequenceTypeModuleDescriptor>(); foreach (ISequenceTypeModuleDescriptor descriptor in sequenceDescriptors) { fileTypes.Add(descriptor.FileExtension); } // Find all files of those types in the data branch. return fileTypes.SelectMany(x => Directory.GetFiles(Paths.DataRootPath, "*" + x, SearchOption.AllDirectories)).ToArray(); }
public ReadOnlyCollection<IField> GetFields(bool includeInherited) { if (includeInherited && _allFields == null) { List<Field> allFields = new List<Field>(GetFields(false).Cast<Field>()); HashSet<ReferenceType> inheritedTypes = new HashSet<ReferenceType>(); GetInheritedTypes(this, inheritedTypes); allFields.AddRange(inheritedTypes.SelectMany(type => type.GetFields(false)).Cast<Field>()); _allFields = allFields.ToArray(); } else if (!includeInherited && _fields == null) { DeclaredFieldData[] fieldData; DebugErrorHandler.ThrowOnFailure(VirtualMachine.ProtocolService.GetFields(out fieldData, ReferenceTypeId)); Field[] fields = Array.ConvertAll(fieldData, field => VirtualMachine.GetMirrorOf(this, field)); _fields = fields; } return new ReadOnlyCollection<IField>(includeInherited ? _allFields : _fields); }
public void ProcessMap_ValidInput_AllCellsAreReachable() { var map = GenerateMap(); var visitedCells = new HashSet<Cell>(); var discoveredCells = new HashSet<Cell>() { map.AllCells.FirstOrDefault(cell => cell.Terrain == TerrainType.Floor) }; while (discoveredCells.Any()) { foreach (var discoveredCell in discoveredCells) { visitedCells.Add(discoveredCell); } var newDiscoveredCells = new HashSet<Cell>(); foreach (var newDiscoveredCell in discoveredCells.SelectMany(cell => map.GetAllAdjacentCells(cell) .Where(c => c.Terrain != TerrainType.Rock && !visitedCells.Contains(c)))) { newDiscoveredCells.Add(newDiscoveredCell); } discoveredCells = newDiscoveredCells; } var unReachable = map.AllCells.Where(cell => cell.Terrain != TerrainType.Rock).Except(visitedCells).ToList(); Assert.AreEqual(map.AllCells.Count(cell => cell.Terrain != TerrainType.Rock), visitedCells.Count); }
public void ProcessMap_ValidInput_AllCellsAreReachable() { var map = GenerateMap(); var visitedCells = new HashSet<BinaryCell>(); var discoveredCells = new HashSet<BinaryCell>() { map.GetCell(0, 0) }; while (discoveredCells.Any()) { foreach (var discoveredCell in discoveredCells) { visitedCells.Add(discoveredCell); } var newDiscoveredCells = new HashSet<BinaryCell>(); foreach (var newDiscoveredCell in discoveredCells.SelectMany(cell => cell.Sides .Where(pair => pair.Value && !visitedCells.Contains(map.GetAdjacentCell(cell, pair.Key))) .Select(pair => map.GetAdjacentCell(cell, pair.Key)))) { newDiscoveredCells.Add(newDiscoveredCell); } discoveredCells = newDiscoveredCells; } Assert.AreEqual(map.AllCells.Count(), visitedCells.Count); }
public override async Task<IEnumerable<PackageDependencyInfo>> ResolvePackages(IEnumerable<PackageIdentity> packages, NuGetFramework projectFramework, bool includePrerelease, CancellationToken token) { var results = new HashSet<PackageDependencyInfo>( Packages.Where(e => packages.Contains(e, PackageIdentity.Comparer)), PackageIdentity.Comparer); bool complete = false; while (!complete) { var dependencies = results.SelectMany(e => e.Dependencies).Select(e => e.Id).Distinct(StringComparer.OrdinalIgnoreCase); int before = results.Count; results.UnionWith(Packages.Where(e => dependencies.Contains(e.Id, StringComparer.OrdinalIgnoreCase))); complete = before == results.Count; } return results; }
void TriangleSelectionToolbox() { if (plotter.CurrentAction != HairyPlotterActions.VertexUvEdit) { if (plotter.TriangleSelectionCount > 0) { EditorGUILayout.LabelField("Triangle Selection: " + plotter.TriangleSelectionCount, EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); GUI.color = TriangleSelectionToolbarColor; if (GUILayout.Button("Create Unique Vertices", EditorStyles.miniButton)) { HashSet<HairyPlotterTriangle> selectedTriangles = new HashSet<HairyPlotterTriangle>(plotter.SelectedTriangles); HashSet<HairyPlotterVertex> uniqueVertices = new HashSet<HairyPlotterVertex>(selectedTriangles.SelectMany(x => x.VertexObjects).Distinct()); // Iterate over each vertex that the selectedTriangles use foreach (HairyPlotterVertex vertex in uniqueVertices) { // Iterate over each triangle the vertex blongs to foreach (HairyPlotterTriangle vertexTriangle in vertex.TriangleSet) { // If the triangle is NOT in the selected triangles if (!selectedTriangles.Contains(vertexTriangle)) { // Create a clone of the vertex HairyPlotterVertex vertexClone = plotter.CreateVertex(vertex.Position, vertex.Uv); // And step through each selected triangle, and switch out the shared vertex for the clone foreach (HairyPlotterTriangle selectedTriangle in selectedTriangles) { selectedTriangle.SwitchVertices(vertex, vertexClone); } // We're done break; } } } plotter.Dirty = true; plotter.UpdateVertexIndexes(); } if (GUILayout.Button("Select Vertices", EditorStyles.miniButton)) { HashSet<HairyPlotterTriangle> selectedTriangles = new HashSet<HairyPlotterTriangle>(plotter.SelectedTriangles); HashSet<HairyPlotterVertex> selectedTrianglesVertices = new HashSet<HairyPlotterVertex>(selectedTriangles.SelectMany(x => x.VertexObjects)); plotter.ClearVertexSelection(); foreach (HairyPlotterVertex vertex in selectedTrianglesVertices) { plotter.AddSelection(vertex); } // Clear triangle selection plotter.ClearTriangleSelection(); } if (GUILayout.Button("Clear Selection", EditorStyles.miniButton)) { plotter.ClearTriangleSelection(); } if (plotter.CurrentAction == HairyPlotterActions.TriangleDelete) { if (GUILayout.Button("Yes!", EditorStyles.miniButton)) { foreach (HairyPlotterTriangle triangle in plotter.SelectedTriangles) { plotter.DestroyTriangle(triangle); } plotter.CurrentAction = HairyPlotterActions.None; } if (GUILayout.Button("No!", EditorStyles.miniButton)) { plotter.CurrentAction = HairyPlotterActions.None; } } else { if (GUILayout.Button("Delete Selected", EditorStyles.miniButton)) { plotter.CurrentAction = HairyPlotterActions.TriangleDelete; } } GUI.color = Color.white; EditorGUILayout.EndHorizontal(); } } }
internal void NodeFromSelection(IEnumerable<dynNode> selectedNodes) { var selectedNodeSet = new HashSet<dynNode>(selectedNodes); #region Prompt //First, prompt the user to enter a name string newNodeName, newNodeCategory; string error = ""; do { var dialog = new FunctionNamePrompt(Bench.addMenuCategoryDict.Keys, error); if (dialog.ShowDialog() != true) { return; } newNodeName = dialog.Text; newNodeCategory = dialog.Category; if (FunctionDict.ContainsKey(newNodeName)) { error = "A function with this name already exists."; } else if (newNodeCategory.Equals("")) { error = "Please enter a valid category."; } else { error = ""; } } while (!error.Equals("")); var newNodeWorkspace = NewFunction(newNodeName, newNodeCategory, false); #endregion CurrentSpace.DisableReporting(); #region UI Positioning Calculations var avgX = selectedNodeSet.Average(node => Canvas.GetLeft(node.NodeUI)); var avgY = selectedNodeSet.Average(node => Canvas.GetTop(node.NodeUI)); var leftMost = selectedNodeSet.Min(node => Canvas.GetLeft(node.NodeUI)); var topMost = selectedNodeSet.Min(node => Canvas.GetTop(node.NodeUI)); var rightMost = selectedNodeSet.Max(node => Canvas.GetLeft(node.NodeUI) + node.NodeUI.Width); #endregion #region Determine Inputs and Outputs //Step 1: determine which nodes will be inputs to the new node var inputs = new HashSet<Tuple<dynNode, int, Tuple<int, dynNode>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.InPortData.Count).Where(node.HasInput).Select( data => Tuple.Create(node, data, node.Inputs[data])).Where( input => !selectedNodeSet.Contains(input.Item3.Item2)))); var outputs = new HashSet<Tuple<dynNode, int, Tuple<int, dynNode>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count).Where(node.HasOutput).SelectMany( data => node.Outputs[data] .Where(output => !selectedNodeSet.Contains(output.Item2)) .Select(output => Tuple.Create(node, data, output))))); #endregion #region Detect 1-node holes (higher-order function extraction) var curriedNodeArgs = new HashSet<dynNode>( inputs .Select(x => x.Item3.Item2) .Intersect(outputs.Select(x => x.Item3.Item2))) .Select( outerNode => { var node = new dynApply1(); var nodeUI = node.NodeUI; NodeNameAttribute elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), true)[0] as NodeNameAttribute; if (elNameAttrib != null) { nodeUI.NickName = elNameAttrib.Name; } nodeUI.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); Bench.WorkBench.Children.Add(nodeUI); //Place it in an appropriate spot Canvas.SetLeft(nodeUI, Canvas.GetLeft(outerNode.NodeUI)); Canvas.SetTop(nodeUI, Canvas.GetTop(outerNode.NodeUI)); //Fetch all input ports // in order // that have inputs // and whose input comes from an inner node var inPortsConnected = Enumerable.Range(0, outerNode.InPortData.Count) .Where(x => outerNode.HasInput(x) && selectedNodeSet.Contains(outerNode.Inputs[x].Item2)) .ToList(); var nodeInputs = outputs .Where(output => output.Item3.Item2 == outerNode) .Select( output => new { InnerNodeInputSender = output.Item1, OuterNodeInPortData = output.Item3.Item1 }).ToList(); nodeInputs.ForEach(_ => node.AddInput()); node.NodeUI.RegisterAllPorts(); Bench.WorkBench.UpdateLayout(); return new { OuterNode = outerNode, InnerNode = node, Outputs = inputs.Where(input => input.Item3.Item2 == outerNode) .Select(input => input.Item3.Item1), Inputs = nodeInputs, OuterNodePortDataList = inPortsConnected }; }).ToList(); #endregion #region Move selection to new workspace var connectors = new HashSet<dynConnector>( CurrentSpace.Connectors.Where( conn => selectedNodeSet.Contains(conn.Start.Owner.NodeLogic) && selectedNodeSet.Contains(conn.End.Owner.NodeLogic))); //Step 2: move all nodes to new workspace // remove from old CurrentSpace.Nodes.RemoveAll(selectedNodeSet.Contains); CurrentSpace.Connectors.RemoveAll(connectors.Contains); // add to new newNodeWorkspace.Nodes.AddRange(selectedNodeSet); newNodeWorkspace.Connectors.AddRange(connectors); var leftShift = leftMost - 250; foreach (var node in newNodeWorkspace.Nodes.Select(x => x.NodeUI)) { Canvas.SetLeft(node, Canvas.GetLeft(node) - leftShift); Canvas.SetTop(node, Canvas.GetTop(node) - topMost); } #endregion #region Insert new node replacement into the current workspace //Step 5: insert new node into original workspace var collapsedNode = new dynFunction( inputs.Select(x => x.Item1.InPortData[x.Item2].NickName), outputs .Where(x => !curriedNodeArgs.Any(y => y.OuterNode == x.Item3.Item2)) .Select(x => x.Item1.OutPortData[x.Item2].NickName), newNodeName); collapsedNode.NodeUI.GUID = Guid.NewGuid(); CurrentSpace.Nodes.Add(collapsedNode); collapsedNode.WorkSpace = CurrentSpace; Bench.WorkBench.Children.Add(collapsedNode.NodeUI); Canvas.SetLeft(collapsedNode.NodeUI, avgX); Canvas.SetTop(collapsedNode.NodeUI, avgY); Bench.WorkBench.UpdateLayout(); #endregion #region Destroy all hanging connectors //Step 6: connect inputs and outputs foreach (var connector in CurrentSpace.Connectors .Where(c => selectedNodeSet.Contains(c.Start.Owner.NodeLogic) && !selectedNodeSet.Contains(c.End.Owner.NodeLogic)).ToList()) { connector.Kill(); } foreach (var connector in CurrentSpace.Connectors .Where(c => !selectedNodeSet.Contains(c.Start.Owner.NodeLogic) && selectedNodeSet.Contains(c.End.Owner.NodeLogic)).ToList()) { connector.Kill(); } #endregion newNodeWorkspace.Nodes.ForEach(x => x.DisableReporting()); #region Process inputs //Step 3: insert variables (reference step 1) foreach (var input in Enumerable.Range(0, inputs.Count).Zip(inputs, Tuple.Create)) { var inputIndex = input.Item1; var inputReceiverNode = input.Item2.Item1; var inputReceiverData = input.Item2.Item2; var inputNode = input.Item2.Item3.Item2; var inputData = input.Item2.Item3.Item1; //Connect outside input to the node CurrentSpace.Connectors.Add( new dynConnector( inputNode.NodeUI, collapsedNode.NodeUI, inputData, inputIndex, 0, true)); //Create Symbol Node dynSymbol node = new dynSymbol() { Symbol = inputReceiverNode.InPortData[inputReceiverData].NickName }; var nodeUI = node.NodeUI; NodeNameAttribute elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), true)[0] as NodeNameAttribute; if (elNameAttrib != null) { nodeUI.NickName = elNameAttrib.Name; } nodeUI.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); Bench.WorkBench.Children.Add(nodeUI); //Place it in an appropriate spot Canvas.SetLeft(nodeUI, 0); Canvas.SetTop(nodeUI, inputIndex * (50 + node.NodeUI.Height)); Bench.WorkBench.UpdateLayout(); var curriedNode = curriedNodeArgs.FirstOrDefault( x => x.OuterNode == inputNode); if (curriedNode == null) { //Connect it (new dynConnector) newNodeWorkspace.Connectors.Add(new dynConnector( nodeUI, inputReceiverNode.NodeUI, 0, inputReceiverData, 0, false)); } else { //Connect it to the applier newNodeWorkspace.Connectors.Add(new dynConnector( nodeUI, curriedNode.InnerNode.NodeUI, 0, 0, 0, false)); //Connect applier to the inner input receiver newNodeWorkspace.Connectors.Add(new dynConnector( curriedNode.InnerNode.NodeUI, inputReceiverNode.NodeUI, 0, inputReceiverData, 0, false)); } } #endregion #region Process outputs //List of all inner nodes to connect an output. Unique. var outportList = new List<Tuple<dynNode, int>>(); int i = 0; foreach (var output in outputs) { if (outportList.All(x => !(x.Item1 == output.Item1 && x.Item2 == output.Item2))) { var outputSenderNode = output.Item1; var outputSenderData = output.Item2; var outputReceiverNode = output.Item3.Item2; if (curriedNodeArgs.Any(x => x.OuterNode == outputReceiverNode)) continue; outportList.Add(Tuple.Create(outputSenderNode, outputSenderData)); //Create Symbol Node var node = new dynOutput() { Symbol = outputSenderNode.OutPortData[outputSenderData].NickName }; var nodeUI = node.NodeUI; NodeNameAttribute elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), false)[0] as NodeNameAttribute; if (elNameAttrib != null) { nodeUI.NickName = elNameAttrib.Name; } nodeUI.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); Bench.WorkBench.Children.Add(nodeUI); //Place it in an appropriate spot Canvas.SetLeft(nodeUI, rightMost + 75 - leftShift); Canvas.SetTop(nodeUI, i * (50 + node.NodeUI.Height)); Bench.WorkBench.UpdateLayout(); newNodeWorkspace.Connectors.Add(new dynConnector( outputSenderNode.NodeUI, nodeUI, outputSenderData, 0, 0, false)); i++; } } //Connect outputs to new node foreach (var output in outputs) { //Node to be connected to in CurrentSpace var outputSenderNode = output.Item1; //Port to be connected to on outPutNode_outer var outputSenderData = output.Item2; var outputReceiverData = output.Item3.Item1; var outputReceiverNode = output.Item3.Item2; var curriedNode = curriedNodeArgs.FirstOrDefault( x => x.OuterNode == outputReceiverNode); if (curriedNode == null) { CurrentSpace.Connectors.Add( new dynConnector( collapsedNode.NodeUI, outputReceiverNode.NodeUI, outportList.FindIndex(x => x.Item1 == outputSenderNode && x.Item2 == outputSenderData), outputReceiverData, 0, true)); } else { var targetPort = curriedNode.Inputs .First( x => x.InnerNodeInputSender == outputSenderNode) .OuterNodeInPortData; var targetPortIndex = curriedNode.OuterNodePortDataList.IndexOf(targetPort); //Connect it (new dynConnector) newNodeWorkspace.Connectors.Add(new dynConnector( outputSenderNode.NodeUI, curriedNode.InnerNode.NodeUI, outputSenderData, targetPortIndex + 1, 0)); } } #endregion #region Make new workspace invisible //Step 4: make nodes invisible // and update positions foreach (var node in newNodeWorkspace.Nodes.Select(x => x.NodeUI)) node.Visibility = Visibility.Hidden; foreach (var connector in newNodeWorkspace.Connectors) connector.Visible = false; #endregion newNodeWorkspace.Nodes.ForEach(x => { x.EnableReporting(); x.NodeUI.UpdateConnections(); }); collapsedNode.EnableReporting(); collapsedNode.NodeUI.UpdateConnections(); CurrentSpace.EnableReporting(); SaveFunction(newNodeWorkspace, true); }
/// <summary> /// Event handler for the "Find Images" button. Fetches image URL's based on the field values in /// the first tab, and uses that information to set field values in the second tab. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FindImagesButton_Click(object sender, RoutedEventArgs e) { MainTabControl.SelectedItem = DownloadImagesTabItem; // TODO: Refactor, and make this asynchronous so it doesn't block the main UI thread // Get user input from XAML fields string entity = EntityTextBox.Text; RedditEntity type = (UserEntityType.IsChecked == true) ? RedditEntity.User : RedditEntity.Subreddit; int maxPages; if (!int.TryParse(MaxPagesTextBox.Text, out maxPages)) maxPages = 1; // Parse Imgur image and album URL's for the given Reddit user or subuser, stopping when we // either run out of pages or else hit the maximum page count HashSet<string> imageUrls = new HashSet<string>(); HashSet<string> albumUrls = new HashSet<string>(); string nextPageCursor = ""; int pageCount = 1; for ( ; pageCount <= maxPages && nextPageCursor != null; pageCount++) { Console.WriteLine("Processing page {0} for {1} {2}", pageCount, type.ToString().ToLower(), entity); Uri redditUrl = RedditUtils.BuildUrl(entity, type, "".Equals(nextPageCursor) ? null : nextPageCursor); RedditUtils.ParsePage(redditUrl, ref imageUrls, ref albumUrls, out nextPageCursor); if (nextPageCursor != null) Console.WriteLine("nextPageCursor == {0}", nextPageCursor); } Console.WriteLine("Parsed {0} image URL's and {1} album URL's from {2} pages", imageUrls.Count, albumUrls.Count, pageCount); // Parse out image URL's from the albums var imagesFromAlbums = albumUrls.SelectMany(albumUrl => ImgurUtils.ParseAlbum(new Uri(albumUrl))); imageUrls.UnionWith(imagesFromAlbums); Console.WriteLine("There are {0} total images after extracting {1} from albums", imageUrls.Count, imagesFromAlbums.ToList().Count); PageCountLabel.Content = pageCount; ImagesCountLabel.Content = imageUrls.Count; ImagesDataGrid.ItemsSource = imageUrls.Select(imageUrl => new ImgurUrl { URL = imageUrl }); }
private static int Process(Options options) { try { Console.WriteLine("Start Process!"); // Resolve options var basePath = Path.GetFullPath(options.Path ?? "."); var sources = options.Sources.Where(p => string.IsNullOrWhiteSpace(p) == false && p.ToLower().IndexOf(".codegen.cs") == -1) .Select(p => MakeFullPath(p, basePath)) .ToArray(); var references = options.References.Where(p => string.IsNullOrWhiteSpace(p) == false) .Select(p => MakeFullPath(p, basePath)) .ToArray(); var targetDefaultPath = @".\Properties\TrackableData.CodeGen.cs"; var targetPath = MakeFullPath(options.TargetFile ?? targetDefaultPath, basePath); // Parse sources and extract interfaces Console.WriteLine("- Parse sources"); var syntaxTrees = sources.Select( file => CSharpSyntaxTree.ParseText(File.ReadAllText(file), path: file)).ToArray(); var interfaceDeclarations = syntaxTrees.SelectMany( st => st.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>()).ToArray(); // Generate code Console.WriteLine("- Generate code"); var settings = new CodeWriterSettings(CodeWriterSettings.CSharpDefault); settings.TranslationMapping["`"] = "\""; var w = new CodeWriter.CodeWriter(settings); var relatedSourceTrees = new HashSet<SyntaxNode>(); w.HeadLines = new List<string> { "// ------------------------------------------------------------------------------", "// <auto-generated>", "// This code was generated by TrackableData.CodeGenerator.", "//", "// Changes to this file may cause incorrect behavior and will be lost if", "// the code is regenerated.", "// </auto-generated>", "// ------------------------------------------------------------------------------", "", "using System;", "using System.Collections.Generic;", "using System.Reflection;", "using System.Runtime.Serialization;", "using System.Linq;", "using System.Text;", "using TrackableData;", "" }; // TrackablePoco var pocoCodeGen = new TrackablePocoCodeGenerator() { Options = options }; foreach (var idecl in interfaceDeclarations) { var baseType = idecl.GetGenericBase("TrackableData.ITrackablePoco"); if (baseType != null) { var pocoType = baseType.TypeArgumentList.Arguments[0].ToString(); if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), pocoType) == false) { throw new Exception($"Invalid base type of ITrackablePoco<{pocoType}>"); } pocoCodeGen.GenerateCode(idecl, w); relatedSourceTrees.Add(idecl.GetRootNode()); } } // TrackableContainer var containerCodeGen = new TrackableContainerCodeGenerator() { Options = options }; foreach (var idecl in interfaceDeclarations) { var baseType = idecl.GetGenericBase("TrackableData.ITrackableContainer"); if (baseType != null) { var containerType = baseType.TypeArgumentList.Arguments[0].ToString(); if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), containerType) == false) { throw new Exception($"Invalid base type of ITrackableContainer<{containerType}>"); } containerCodeGen.GenerateCode(idecl, w); relatedSourceTrees.Add(idecl.GetRootNode()); } } // Resolve referenced using var usingDirectives = new HashSet<string>(relatedSourceTrees.SelectMany( st => st.DescendantNodes().OfType<UsingDirectiveSyntax>()).Select(x => x.Name.ToString())); foreach (var usingDirective in usingDirectives) EnsureUsing(w, usingDirective); // Save generated code Console.WriteLine("- Save code"); if (w.WriteAllText(targetPath, true) == false) Console.WriteLine("Nothing changed. Skip writing."); return 0; } catch (Exception e) { Console.WriteLine("Exception in processing:\n" + e); return 1; } }
public static List<CollectionElementToken> GetElements(HashSet<QueryToken> allTokens) { return allTokens .SelectMany(t => t.Follow(tt => tt.Parent)) .OfType<CollectionElementToken>() .Where(a => a.CollectionElementType.IsElement()) .Distinct() .OrderBy(a => a.FullKey().Length) .ToList(); }
private static int Process(Options options) { try { Console.WriteLine("Start Process!"); // Resolve options var basePath = Path.GetFullPath(options.Path ?? "."); var sources = options.Sources.Where(p => string.IsNullOrWhiteSpace(p) == false && p.ToLower().IndexOf(".codegen.cs") == -1) .Select(p => MakeFullPath(p, basePath)) .ToArray(); var references = options.References.Where(p => string.IsNullOrWhiteSpace(p) == false) .Select(p => MakeFullPath(p, basePath)) .ToArray(); var targetDefaultPath = @".\Properties\TrackableData.CodeGen.cs"; var targetPath = MakeFullPath(options.TargetFile ?? targetDefaultPath, basePath); // Parse sources and extract interfaces Console.WriteLine("- Parse sources"); var syntaxTrees = sources.Select( file => CSharpSyntaxTree.ParseText(File.ReadAllText(file), path: file)).ToArray(); var interfaceDeclarations = syntaxTrees.SelectMany( st => st.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>()).ToArray(); // Generate code Console.WriteLine("- Generate code"); var writer = new TextCodeGenWriter(); var relatedSourceTrees = new HashSet<SyntaxNode>(); // TrackablePoco var pocoCodeGen = new TrackablePocoCodeGenerator() { Options = options }; foreach (var idecl in interfaceDeclarations) { var baseType = idecl.GetGenericBase("TrackableData.ITrackablePoco"); if (baseType != null) { var pocoType = baseType.TypeArgumentList.Arguments[0].ToString(); if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), pocoType) == false) { throw new Exception($"Invalid base type of ITrackablePoco<{pocoType}>"); } pocoCodeGen.GenerateCode(idecl, writer); relatedSourceTrees.Add(idecl.GetRootNode()); } } // TrackableContainer var containerCodeGen = new TrackableContainerCodeGenerator() { Options = options }; foreach (var idecl in interfaceDeclarations) { var baseType = idecl.GetGenericBase("TrackableData.ITrackableContainer"); if (baseType != null) { var containerType = baseType.TypeArgumentList.Arguments[0].ToString(); if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), containerType) == false) { throw new Exception($"Invalid base type of ITrackableContainer<{containerType}>"); } containerCodeGen.GenerateCode(idecl, writer); relatedSourceTrees.Add(idecl.GetRootNode()); } } // Resolve referenced using var usingDirectives = new HashSet<string>(relatedSourceTrees.SelectMany( st => st.DescendantNodes().OfType<UsingDirectiveSyntax>()).Select(x => x.Name.ToString())); usingDirectives.Add("System"); usingDirectives.Add("System.Collections.Generic"); usingDirectives.Add("System.Reflection"); usingDirectives.Add("System.Runtime.Serialization"); usingDirectives.Add("System.Linq"); usingDirectives.Add("System.Text"); usingDirectives.Add("TrackableData"); foreach (var usingDirective in usingDirectives) writer.AddUsing(usingDirective); // Save generated code Console.WriteLine("- Save code"); if (SaveFileIfChanged(targetPath, writer.ToString()) == false) Console.WriteLine("Nothing changed. Skip writing."); return 0; } catch (Exception e) { Console.WriteLine("Exception in processing:\n" + e); return 1; } }
/// <summary> /// Collapse a set of nodes in a given workspace. Has the side effects of prompting the user /// first in order to obtain the name and category for the new node, /// writes the function to a dyf file, adds it to the FunctionDict, adds it to search, and compiles and /// places the newly created symbol (defining a lambda) in the Controller's FScheme Environment. /// </summary> /// <param name="selectedNodes"> The function definition for the user-defined node </param> /// <param name="currentWorkspace"> The workspace where</param> public static void Collapse(IEnumerable<NodeModel> selectedNodes, WorkspaceModel currentWorkspace, FunctionNamePromptEventArgs args=null) { var selectedNodeSet = new HashSet<NodeModel>(selectedNodes); if (args == null || !args.Success) { args = new FunctionNamePromptEventArgs(); dynSettings.Controller.DynamoModel.OnRequestsFunctionNamePrompt(null, args); //if (!dynSettings.Controller.DynamoViewModel.ShowNewFunctionDialog(ref newNodeName, ref newNodeCategory)) if (!args.Success) { return; } } var newNodeWorkspace = new CustomNodeWorkspaceModel(args.Name, args.Category, args.Description, 0, 0) { WatchChanges = false, HasUnsavedChanges = true }; var newNodeDefinition = new FunctionDefinition(Guid.NewGuid()) { WorkspaceModel = newNodeWorkspace }; currentWorkspace.DisableReporting(); #region Determine Inputs and Outputs //Step 1: determine which nodes will be inputs to the new node var inputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.InPortData.Count).Where(node.HasConnectedInput) .Select(data => Tuple.Create(node, data, node.Inputs[data])) .Where(input => !selectedNodeSet.Contains(input.Item3.Item2)))); var outputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count).Where(node.HasOutput).SelectMany( data => node.Outputs[data] .Where(output => !selectedNodeSet.Contains(output.Item2)) .Select(output => Tuple.Create(node, data, output))))); #endregion #region Detect 1-node holes (higher-order function extraction) var curriedNodeArgs = new HashSet<NodeModel>( inputs .Select(x => x.Item3.Item2) .Intersect(outputs.Select(x => x.Item3.Item2))) .Select( outerNode => { var node = new Apply1(); //MVVM : Don't make direct reference to view here //MVVM: no reference to view here //dynNodeView nodeUI = node.NodeUI; var elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), true)[0] as NodeNameAttribute; if (elNameAttrib != null) { node.NickName = elNameAttrib.Name; } node.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); //MVVM : Can't set view location here //dynSettings.Bench.WorkBench.Children.Add(nodeUI); //Place it in an appropriate spot //Canvas.SetLeft(nodeUI, Canvas.GetLeft(outerNode.NodeUI)); //Canvas.SetTop(nodeUI, Canvas.GetTop(outerNode.NodeUI)); node.X = outerNode.X; node.Y = outerNode.Y; //Fetch all input ports // in order // that have inputs // and whose input comes from an inner node List<int> inPortsConnected = Enumerable.Range(0, outerNode.InPortData.Count) .Where( x => outerNode.HasInput(x) && selectedNodeSet.Contains( outerNode.Inputs[x].Item2)) .ToList(); var nodeInputs = outputs .Where(output => output.Item3.Item2 == outerNode) .Select( output => new { InnerNodeInputSender = output.Item1, OuterNodeInPortData = output.Item3.Item1 }).ToList(); nodeInputs.ForEach(_ => node.AddInput()); node.RegisterAllPorts(); return new { OuterNode = outerNode, InnerNode = node, Outputs = inputs.Where(input => input.Item3.Item2 == outerNode) .Select(input => input.Item3.Item1), Inputs = nodeInputs, OuterNodePortDataList = inPortsConnected }; }).ToList(); #endregion #region UI Positioning Calculations double avgX = selectedNodeSet.Average(node => node.X); double avgY = selectedNodeSet.Average(node => node.Y); double leftMost = selectedNodeSet.Min(node => node.X); double topMost = selectedNodeSet.Min(node => node.Y); double rightMost = selectedNodeSet.Max(node => node.X + node.Width); #endregion #region Move selection to new workspace var connectors = new HashSet<ConnectorModel>(currentWorkspace.Connectors.Where( conn => selectedNodeSet.Contains(conn.Start.Owner) && selectedNodeSet.Contains(conn.End.Owner))); //Step 2: move all nodes to new workspace // remove from old foreach (var ele in selectedNodeSet) { ele.SaveResult = false; currentWorkspace.Nodes.Remove(ele); ele.WorkSpace = newNodeWorkspace; } foreach (var ele in connectors) { currentWorkspace.Connectors.Remove(ele); } // add to new newNodeWorkspace.Nodes.AddRange(selectedNodeSet); newNodeWorkspace.Connectors.AddRange(connectors); double leftShift = leftMost - 250; foreach (NodeModel node in newNodeWorkspace.Nodes) { node.X = node.X - leftShift; node.Y = node.Y - topMost; } #endregion #region Insert new node into the current workspace //Step 5: insert new node into original workspace //var collapsedNode = dynSettings.Controller.DynamoViewModel.CreateFunction( // inputs.Select(x => x.Item1.InPortData[x.Item2].NickName), // outputs // .Where(x => !curriedNodeArgs.Any(y => y.OuterNode == x.Item3.Item2)) // .Select(x => x.Item1.OutPortData[x.Item2].NickName), // newNodeDefinition); //collapsedNode.GUID = Guid.NewGuid(); //currentWorkspace.Nodes.Add(collapsedNode); //collapsedNode.WorkSpace = currentWorkspace; //collapsedNode.X = avgX; //collapsedNode.Y = avgY; #endregion #region Destroy all hanging connectors //Step 6: connect inputs and outputs var removeConnectors = currentWorkspace.Connectors.Where(c => selectedNodeSet.Contains(c.Start.Owner) || selectedNodeSet.Contains(c.End.Owner)) .ToList(); foreach (ConnectorModel connector in removeConnectors) { connector.NotifyConnectedPortsOfDeletion(); currentWorkspace.Connectors.Remove(connector); } #endregion newNodeWorkspace.Nodes.ToList().ForEach(x => x.DisableReporting()); var inConnectors = new List<Tuple<NodeModel, int, int>>(); #region Process inputs var uniqueInputSenders = new Dictionary<Tuple<NodeModel, int>, Symbol>(); //Step 3: insert variables (reference step 1) foreach (var input in Enumerable.Range(0, inputs.Count).Zip(inputs, Tuple.Create)) { int inputIndex = input.Item1; NodeModel inputReceiverNode = input.Item2.Item1; int inputReceiverData = input.Item2.Item2; NodeModel inputNode = input.Item2.Item3.Item2; int inputData = input.Item2.Item3.Item1; Symbol node; var key = Tuple.Create(inputNode, inputData); if (uniqueInputSenders.ContainsKey(key)) { node = uniqueInputSenders[key]; } else { //MVVM : replace NodeUI reference with node inConnectors.Add(Tuple.Create(inputNode, inputData, inputIndex)); //Create Symbol Node node = new Symbol { InputSymbol = inputReceiverNode.InPortData[inputReceiverData].NickName }; //MVVM : Don't make direct reference to view here //dynNodeView nodeUI = node.NodeUI; var elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), true)[0] as NodeNameAttribute; if (elNameAttrib != null) { node.NickName = elNameAttrib.Name; } node.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); node.X = 0; node.Y = inputIndex * (50 + node.Height); uniqueInputSenders[key] = node; } var curriedNode = curriedNodeArgs.FirstOrDefault(x => x.OuterNode == inputNode); if (curriedNode == null) { var conn1 = ConnectorModel.Make(node, inputReceiverNode, 0, inputReceiverData, PortType.INPUT); if (conn1 != null) newNodeWorkspace.Connectors.Add(conn1); } else { //Connect it to the applier var conn = ConnectorModel.Make(node, curriedNode.InnerNode, 0, 0, PortType.INPUT); if (conn != null) newNodeWorkspace.Connectors.Add(conn); //Connect applier to the inner input receive var conn2 = ConnectorModel.Make( curriedNode.InnerNode, inputReceiverNode, 0, inputReceiverData, PortType.INPUT); if (conn2 != null) newNodeWorkspace.Connectors.Add(conn2); } } #endregion #region Process outputs //List of all inner nodes to connect an output. Unique. var outportList = new List<Tuple<NodeModel, int>>(); var outConnectors = new List<Tuple<NodeModel, int, int>>(); int i = 0; foreach (var output in outputs) { if (outportList.All(x => !(x.Item1 == output.Item1 && x.Item2 == output.Item2))) { NodeModel outputSenderNode = output.Item1; int outputSenderData = output.Item2; NodeModel outputReceiverNode = output.Item3.Item2; if (curriedNodeArgs.Any(x => x.OuterNode == outputReceiverNode)) continue; outportList.Add(Tuple.Create(outputSenderNode, outputSenderData)); //Create Symbol Node var node = new Output { Symbol = outputSenderNode.OutPortData[outputSenderData].NickName }; //dynNodeView nodeUI = node.NodeUI; var elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), false)[0] as NodeNameAttribute; if (elNameAttrib != null) { node.NickName = elNameAttrib.Name; } node.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); node.X = rightMost + 75 - leftShift; node.Y = i*(50 + node.Height); var conn = ConnectorModel.Make( outputSenderNode, node, outputSenderData, 0, PortType.INPUT); if (conn != null) newNodeWorkspace.Connectors.Add(conn); i++; } } //Connect outputs to new node foreach (var output in outputs) { //Node to be connected to in CurrentWorkspace NodeModel outputSenderNode = output.Item1; //Port to be connected to on outPutNode_outer int outputSenderData = output.Item2; int outputReceiverData = output.Item3.Item1; NodeModel outputReceiverNode = output.Item3.Item2; var curriedNode = curriedNodeArgs.FirstOrDefault( x => x.OuterNode == outputReceiverNode); if (curriedNode == null) { // we create the connectors in the current space later //MVVM : replaced multiple dynNodeView refrences with dynNode outConnectors.Add( Tuple.Create( outputReceiverNode, outportList.FindIndex( x => x.Item1 == outputSenderNode && x.Item2 == outputSenderData), outputReceiverData)); } else { int targetPort = curriedNode.Inputs .First( x => x.InnerNodeInputSender == outputSenderNode) .OuterNodeInPortData; int targetPortIndex = curriedNode.OuterNodePortDataList.IndexOf(targetPort); //Connect it (new dynConnector) var conn = ConnectorModel.Make( outputSenderNode, curriedNode.InnerNode, outputSenderData, targetPortIndex + 1, PortType.INPUT); if (conn != null) newNodeWorkspace.Connectors.Add(conn); } } #endregion // save and load the definition from file newNodeDefinition.SyncWithWorkspace(true, true); dynSettings.Controller.DynamoModel.Workspaces.Add(newNodeWorkspace); string name = newNodeDefinition.FunctionId.ToString(); var collapsedNode = dynSettings.Controller.DynamoModel.CreateNode(avgX, avgY, name); // place the node as intended, not centered collapsedNode.X = avgX; collapsedNode.Y = avgY; collapsedNode.DisableReporting(); foreach (var nodeTuple in inConnectors) { var conn = ConnectorModel.Make( nodeTuple.Item1, collapsedNode, nodeTuple.Item2, nodeTuple.Item3, PortType.INPUT); if (conn != null) currentWorkspace.Connectors.Add(conn); } foreach (var nodeTuple in outConnectors) { var conn = ConnectorModel.Make( collapsedNode, nodeTuple.Item1, nodeTuple.Item2, nodeTuple.Item3, PortType.INPUT); if (conn != null) currentWorkspace.Connectors.Add(conn); } collapsedNode.EnableReporting(); currentWorkspace.EnableReporting(); newNodeWorkspace.WatchChanges = true; }
/// <summary> /// Visit the given context and return a collection of the resultant contexts. /// </summary> /// <returns>Zero or more <see cref="IRenderingContext"/> instances, determined by the outcome of this visit.</returns> /// <param name="context">The rendering context to visit.</param> public override IRenderingContext[] Visit(IRenderingContext context) { if(context == null) { throw new ArgumentNullException(nameof(context)); } IEnumerable<IRenderingContext> output = new [] { context }, newlyExposedElements = new RenderingContext[0]; var macroAttribute = context.Element.GetMetalAttribute(ZptConstants.Metal.DefineMacroAttribute); if(macroAttribute != null) { context.TalModel.AddLocal(MACRONAME, macroAttribute.Value); } foreach(var handler in _handlers) { var handlingResult = new HashSet<AttributeHandlingResult>(); foreach(var ctx in output) { var processedBatch = handler.Handle(ctx); handlingResult.Add(processedBatch); } newlyExposedElements = newlyExposedElements.Union(handlingResult.SelectMany(x => x.NewlyExposedContexts)); output = handlingResult.Where(x => x.ContinueHandling).SelectMany(x => x.Contexts).ToArray(); } output = output.Union(newlyExposedElements.SelectMany(x => this.Visit(x))); return output.ToArray(); }
private static ObservableCollection<FileEntryViewModel> ParseStfs(StfsPackage package) { var collection = new ObservableCollection<FileEntryViewModel>(); var allocatedBlocks = new HashSet<int>(); var blockCollisions = new HashSet<int>(); foreach (var fileEntry in package.FlatFileList.Where(f => !f.IsDirectory).OrderBy(f => f.Name)) { var blockList = package.GetFileEntryBlockList(fileEntry); foreach (var block in blockList.Where(b => b.Key.HasValue)) { if (!allocatedBlocks.Contains(block.Key.Value)) allocatedBlocks.Add(block.Key.Value); else blockCollisions.Add(block.Key.Value); } collection.Add(new FileEntryViewModel(fileEntry, blockList, package)); } foreach (var block in blockCollisions.SelectMany(blockCollision => collection.SelectMany(vm => vm.Blocks.Where(b => b.BlockNumber == blockCollision)))) { block.Health = FileBlockHealthStatus.Collision; } return collection; }
/// <summary> /// Find distance of a dependency from a target package. /// A -> B -> C /// C is 2 away from A /// </summary> /// <param name="packageId">package id</param> /// <param name="targets">required targets</param> /// <param name="packages">packages in the solution, only 1 package per id should exist</param> /// <returns>number of levels from a target</returns> public static int GetLowestDistanceFromTarget(string packageId, HashSet<string> targets, IEnumerable<ResolverPackage> packages) { // start with the target packages var walkedPackages = new HashSet<ResolverPackage>(packages.Where(package => targets.Contains(package.Id)), PackageIdentity.Comparer); int level = 0; // walk the packages, starting with the required packages until the given packageId is found // this is done in the simplest possible way to avoid circular dependencies // after 20 levels give up, the level is no longer important for ordering while (level < 20 && !walkedPackages.Any(package => StringComparer.OrdinalIgnoreCase.Equals(package.Id, packageId))) { level++; // find the next level of dependencies var dependencyIds = walkedPackages.SelectMany(package => package.Dependencies.Select(dependency => dependency.Id)).ToList(); var dependencyPackages = packages.Where(package => dependencyIds.Contains(package.Id, StringComparer.OrdinalIgnoreCase)); // add the dependency packages walkedPackages.UnionWith(dependencyPackages); } return level; }
/// <summary>Loop through light box, blank out any previous light data and reset all light emitting sources. The light box during initial loading is the full chunk size.</summary> /// <param name="x1">lower x of light box for dynamic change, 0 for initial full chunk loading</param> /// <param name="x2">upper x of light box for dynamic change, chunk size - 1 for initial full chunk loading</param> /// <param name="y1">lower y of light box for dynamic change, 0 for initial full chunk loading</param> /// <param name="y2">upper y of light box for dynamic change, chunk height - 1 for initial full chunk loading</param> /// <param name="z1">lower z of light box for dynamic change, 0 for initial loading of full chunk</param> /// <param name="z2">upper z of light box for dynamic change, chunk size - 1 for initial full chunk loading</param> /// <param name="initialChunk">chunk being loaded initially or null for dynamic changes because multiple chunks may be affected</param> /// <param name="skyLightMap">world sky lightmap for dynamic change and chunk sky lightmap during initial loading</param> /// <param name="itemLightMap">world item lightmap for dynamic change and chunk item lightmap during initial loading</param> internal static void ResetLightBoxSources(int x1, int x2, int y1, int y2, int z1, int z2, Chunk initialChunk, byte[, ,] skyLightMap, byte[, ,] itemLightMap) { var affectedChunks = new HashSet<Chunk>(); if (initialChunk != null) affectedChunks.Add(initialChunk); for (int x = x1; x <= x2; x++) { for (int z = z1; z <= z2; z++) { //y is the innermost loop so we only retrieve chunks when needed, this is always the supplied initial chunk during initial loading Chunk chunk; if (initialChunk == null) //calculate the chunk if this isnt an initial loading chunk { chunk = WorldData.Chunks[x / Chunk.CHUNK_SIZE, z / Chunk.CHUNK_SIZE]; affectedChunks.Add(chunk); } else { chunk = initialChunk; } for (int y = y1; y <= y2; y++) { //chunk relative coords are needlessly calculated on initial loading, but it doesnt noticeably affect performance and this way it doesnt affect dynamic changes at all int chunkRelativeX = x % Chunk.CHUNK_SIZE; int chunkRelativeZ = z % Chunk.CHUNK_SIZE; if (y > chunk.HeightMap[chunkRelativeX, chunkRelativeZ]) { //transparent block above the heightmap surface, it gets full skylight, transparent blocks cannot be light emitting sources skyLightMap[x, y, z] = SkyHost.BRIGHTEST_SKYLIGHT_STRENGTH; itemLightMap[x, y, z] = 0; //could be a light source item here; this gets checked later continue; } var block = chunk.Blocks[chunkRelativeX, y, chunkRelativeZ]; if (!block.IsTransparent) { //this is a non transparent block; it will have zero sky light and only have item light if this block emits light skyLightMap[x, y, z] = 0; itemLightMap[x, y, z] = block.IsLightSource ? block.LightStrength : (byte)0; } else { //this is a transparent block below the heightmap skyLightMap[x, y, z] = 0; itemLightMap[x, y, z] = 0; //could be a light source item here; this gets checked later } } } } //light source items; more efficient to loop through each affected chunks LightSources here and set the lightbox sources accordingly (better then checking for light source matches on every transparent block) //note: this can redundantly set item lightmap values in these chunks that are outside the light box; this doesnt hurt anything and is probably faster than checking to prevent it foreach (var lightSource in affectedChunks.SelectMany(affectedChunk => affectedChunk.LightSources)) { int x = lightSource.Value.Coords.Xblock; int z = lightSource.Value.Coords.Zblock; if (initialChunk != null) { x %= Chunk.CHUNK_SIZE; z %= Chunk.CHUNK_SIZE; } itemLightMap[x, lightSource.Value.Coords.Yblock, z] = lightSource.Value.LightStrength; } }
private bool CheckMemberRestraint(Member MemberToCheck, Beam StartBeam, MEMBERCLASS MemberClass) { bool output; HashSet<Node> nodes; // Gather all nodes connected to the beam to check or any beams parallel to it nodes = new HashSet<Node>(BeamHelpers.GatherParallelBeams(StartBeam).SelectMany(b => new List<Node>() { b.StartNode, b.EndNode})); // Check if any of the connected members are class above the current member IEnumerable<Member> connectedMembers = nodes.SelectMany(n => n.ConnectedMembers).Where(m => m != null && m != MemberToCheck); if (MemberClass == MEMBERCLASS.PRIMARY) output = connectedMembers.Any(m => this.PrimaryMembers.Contains(m)); else if (MemberClass == MEMBERCLASS.SECONDARY) output = connectedMembers.Any(m => this.PrimaryMembers.Contains(m) || this.SecondaryMembers.Contains(m)); else if (MemberClass == MEMBERCLASS.TERTIARY) output = connectedMembers.Any(m => this.PrimaryMembers.Contains(m) || this.SecondaryMembers.Contains(m) || this.TertiaryMembers.Contains(m)); else output = false; return output; }
private string ConvertToGraphvizDot(Graph graph) { Func<string, string> toName = id => id.Substring(id.LastIndexOf('.') + 1); var tab = " "; var sb = new StringBuilder(); sb.AppendLine("digraph G {"); int i = 0; var renderedMessages = new Dictionary<string, int>(); foreach (var handler in graph.Handlers.Values.OrderByDescending(e => e.IsAggregate)) { Func<string, string> correctId = id => { int count; if (renderedMessages.TryGetValue(id, out count)) return id + "_" + (count + 1); return id + "_1"; }; sb.AppendFormat(tab + "subgraph cluster_{0} {{", ++i).AppendLine(); sb.AppendFormat(tab + tab + "label = \"{0}\";", toName(handler.Id)).AppendLine(); sb.AppendLine(tab + tab + "node [style=filled, shape=record];"); var links = new HashSet<Link>(); foreach (var input in handler.Roots) { var flow = new List<Message> { input }; flow.AddRange(input.Result); for (int j = 0; j < flow.Count - 1; j++) { if (j + 1 < flow.Count) links.Add(new Link { From = flow[j], To = flow[j + 1] }); } } foreach (var link in links) sb.AppendFormat(tab + tab + "\"{0}\" -> \"{1}\"", correctId(link.From.Id), correctId(link.To.Id)).AppendLine(); // set message colors var allMessages = handler.Roots.SelectMany(e => e.Result).Distinct().ToList(); allMessages.AddRange(handler.Roots); foreach (var cmd in allMessages.Where(e => e.IsCommand)) sb.AppendFormat(tab + tab + "\"{0}\"[color=lightblue, label=\"{1}\"];", correctId(cmd.Id), toName(cmd.Id)).AppendLine(); foreach (var evt in allMessages.Where(e => e.IsEvent)) sb.AppendFormat(tab + tab + "\"{0}\"[color=orange, label=\"{1}\"];", correctId(evt.Id), toName(evt.Id)).AppendLine(); sb.AppendLine(tab + "}"); foreach (var msg in links.SelectMany(e => new[] { e.From, e.To }).Distinct()) { int count; renderedMessages.TryGetValue(msg.Id, out count); renderedMessages[msg.Id] = ++count; } } foreach (var kv in renderedMessages.Where(kv => kv.Value > 1)) { int count = kv.Value; for (int j = 0; j < count - 1; j++) for (int k = j + 1; k < count; k++) sb.AppendFormat(tab + "\"{0}_{1}\" -> \"{0}_{2}\"[style=dotted, color=grey, arrowsize=0];", kv.Key, j + 1, k + 1).AppendLine(); //for (int j = 1; j < count; j++) // sb.AppendFormat(tab + "\"{0}_1\" -> \"{0}_{1}\"[style=dotted, color=grey, arrowsize=0];", kv.Key, j + 1).AppendLine(); } sb.AppendLine("}"); return sb.ToString(); }
/// <summary> /// Collapse a set of nodes in a given workspace. /// </summary> /// <param name="dynamoModel">The current DynamoModel</param> /// <param name="selectedNodes"> The function definition for the user-defined node </param> /// <param name="currentWorkspace"> The workspace where</param> /// <param name="args"></param> public static void Collapse(DynamoModel dynamoModel, IEnumerable<NodeModel> selectedNodes, WorkspaceModel currentWorkspace, FunctionNamePromptEventArgs args = null) { var selectedNodeSet = new HashSet<NodeModel>(selectedNodes); if (args == null || !args.Success) { args = new FunctionNamePromptEventArgs(); dynamoModel.OnRequestsFunctionNamePrompt(null, args); if (!args.Success) { return; } } // Note that undoable actions are only recorded for the "currentWorkspace", // the nodes which get moved into "newNodeWorkspace" are not recorded for undo, // even in the new workspace. Their creations will simply be treated as part of // the opening of that new workspace (i.e. when a user opens a file, she will // not expect the nodes that show up to be undoable). // // After local nodes are moved into "newNodeWorkspace" as the result of // conversion, if user performs an undo, new set of nodes will be created in // "currentWorkspace" (not moving those nodes in the "newNodeWorkspace" back // into "currentWorkspace"). In another word, undo recording is on a per- // workspace basis, it does not work across different workspaces. // UndoRedoRecorder undoRecorder = currentWorkspace.UndoRecorder; using (undoRecorder.BeginActionGroup()) { var newNodeWorkspace = new CustomNodeWorkspaceModel( dynamoModel, args.Name, args.Category, args.Description, 0, 0) { WatchChanges = false, HasUnsavedChanges = true }; var newNodeDefinition = new CustomNodeDefinition(Guid.NewGuid()) { WorkspaceModel = newNodeWorkspace }; currentWorkspace.DisableReporting(); #region Determine Inputs and Outputs //Step 1: determine which nodes will be inputs to the new node var inputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.InPortData.Count) .Where(node.HasConnectedInput) .Select(data => Tuple.Create(node, data, node.Inputs[data])) .Where(input => !selectedNodeSet.Contains(input.Item3.Item2)))); var outputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count) .Where(node.HasOutput) .SelectMany( data => node.Outputs[data].Where( output => !selectedNodeSet.Contains(output.Item2)) .Select(output => Tuple.Create(node, data, output))))); #endregion #region Detect 1-node holes (higher-order function extraction) var curriedNodeArgs = new HashSet<NodeModel>( inputs.Select(x => x.Item3.Item2) .Intersect(outputs.Select(x => x.Item3.Item2))).Select( outerNode => { //var node = new Apply1(); var node = newNodeWorkspace.AddNode<Apply1>(); node.SetNickNameFromAttribute(); node.DisableReporting(); node.X = outerNode.X; node.Y = outerNode.Y; //Fetch all input ports // in order // that have inputs // and whose input comes from an inner node List<int> inPortsConnected = Enumerable.Range(0, outerNode.InPortData.Count) .Where( x => outerNode.HasInput(x) && selectedNodeSet.Contains( outerNode.Inputs[x].Item2)) .ToList(); var nodeInputs = outputs.Where(output => output.Item3.Item2 == outerNode) .Select( output => new { InnerNodeInputSender = output.Item1, OuterNodeInPortData = output.Item3.Item1 }) .ToList(); nodeInputs.ForEach(_ => node.AddInput()); node.RegisterAllPorts(); return new { OuterNode = outerNode, InnerNode = node, Outputs = inputs.Where( input => input.Item3.Item2 == outerNode) .Select(input => input.Item3.Item1), Inputs = nodeInputs, OuterNodePortDataList = inPortsConnected }; }).ToList(); #endregion #region UI Positioning Calculations double avgX = selectedNodeSet.Average(node => node.X); double avgY = selectedNodeSet.Average(node => node.Y); double leftMost = selectedNodeSet.Min(node => node.X); double topMost = selectedNodeSet.Min(node => node.Y); double rightMost = selectedNodeSet.Max(node => node.X + node.Width); #endregion #region Handle full selected connectors // Step 2: Determine all the connectors whose start/end owners are // both in the selection set, and then move them from the current // workspace into the new workspace. var fullySelectedConns = new HashSet<ConnectorModel>( currentWorkspace.Connectors.Where( conn => { bool startSelected = selectedNodeSet.Contains(conn.Start.Owner); bool endSelected = selectedNodeSet.Contains(conn.End.Owner); return startSelected && endSelected; })); foreach (var ele in fullySelectedConns) { undoRecorder.RecordDeletionForUndo(ele); currentWorkspace.Connectors.Remove(ele); } #endregion #region Handle partially selected connectors // Step 3: Partially selected connectors (either one of its start // and end owners is in the selection) are to be destroyed. var partiallySelectedConns = currentWorkspace.Connectors.Where( conn => selectedNodeSet.Contains(conn.Start.Owner) || selectedNodeSet.Contains(conn.End.Owner)).ToList(); foreach (ConnectorModel connector in partiallySelectedConns) { undoRecorder.RecordDeletionForUndo(connector); connector.NotifyConnectedPortsOfDeletion(); currentWorkspace.Connectors.Remove(connector); } #endregion #region Transfer nodes and connectors to new workspace // Step 4: move all nodes to new workspace remove from old // PB: This could be more efficiently handled by a copy paste, but we // are preservering the node foreach (var ele in selectedNodeSet) { undoRecorder.RecordDeletionForUndo(ele); ele.SaveResult = false; currentWorkspace.Nodes.Remove(ele); ele.Workspace = newNodeWorkspace; } // add to new newNodeWorkspace.Nodes.AddRange(selectedNodeSet); newNodeWorkspace.Connectors.AddRange(fullySelectedConns); foreach (var node in newNodeWorkspace.Nodes) node.DisableReporting(); double leftShift = leftMost - 250; foreach (NodeModel node in newNodeWorkspace.Nodes) { node.X = node.X - leftShift; node.Y = node.Y - topMost; } #endregion #region Process inputs var inConnectors = new List<Tuple<NodeModel, int>>(); var uniqueInputSenders = new Dictionary<Tuple<NodeModel, int>, Symbol>(); //Step 3: insert variables (reference step 1) foreach (var input in Enumerable.Range(0, inputs.Count).Zip(inputs, Tuple.Create)) { int inputIndex = input.Item1; NodeModel inputReceiverNode = input.Item2.Item1; int inputReceiverData = input.Item2.Item2; NodeModel inputNode = input.Item2.Item3.Item2; int inputData = input.Item2.Item3.Item1; Symbol node; var key = Tuple.Create(inputNode, inputData); if (uniqueInputSenders.ContainsKey(key)) { node = uniqueInputSenders[key]; } else { inConnectors.Add(Tuple.Create(inputNode, inputData)); node = newNodeWorkspace.AddNode<Symbol>(); node.InputSymbol = inputReceiverNode.InPortData[inputReceiverData].NickName; node.SetNickNameFromAttribute(); node.DisableReporting(); node.X = 0; node.Y = inputIndex*(50 + node.Height); uniqueInputSenders[key] = node; } var curriedNode = curriedNodeArgs.FirstOrDefault(x => x.OuterNode == inputNode); if (curriedNode == null) { newNodeWorkspace.AddConnection( node, inputReceiverNode, 0, inputReceiverData); } else { //Connect it to the applier newNodeWorkspace.AddConnection(node, curriedNode.InnerNode, 0, 0); //Connect applier to the inner input receive newNodeWorkspace.AddConnection( curriedNode.InnerNode, inputReceiverNode, 0, inputReceiverData); } } #endregion #region Process outputs //List of all inner nodes to connect an output. Unique. var outportList = new List<Tuple<NodeModel, int>>(); var outConnectors = new List<Tuple<NodeModel, int, int>>(); int i = 0; if (outputs.Any()) { foreach (var output in outputs) { if ( outportList.All( x => !(x.Item1 == output.Item1 && x.Item2 == output.Item2))) { NodeModel outputSenderNode = output.Item1; int outputSenderData = output.Item2; NodeModel outputReceiverNode = output.Item3.Item2; if (curriedNodeArgs.Any(x => x.OuterNode == outputReceiverNode)) continue; outportList.Add(Tuple.Create(outputSenderNode, outputSenderData)); //Create Symbol Node var node = newNodeWorkspace.AddNode<Output>(); node.Symbol = outputSenderNode.OutPortData[outputSenderData].NickName; node.SetNickNameFromAttribute(); node.DisableReporting(); node.X = rightMost + 75 - leftShift; node.Y = i*(50 + node.Height); newNodeWorkspace.AddConnection( outputSenderNode, node, outputSenderData, 0); i++; } } //Connect outputs to new node foreach (var output in outputs) { //Node to be connected to in CurrentWorkspace NodeModel outputSenderNode = output.Item1; //Port to be connected to on outPutNode_outer int outputSenderData = output.Item2; int outputReceiverData = output.Item3.Item1; NodeModel outputReceiverNode = output.Item3.Item2; var curriedNode = curriedNodeArgs.FirstOrDefault(x => x.OuterNode == outputReceiverNode); if (curriedNode == null) { // we create the connectors in the current space later outConnectors.Add( Tuple.Create( outputReceiverNode, outportList.FindIndex( x => x.Item1 == outputSenderNode && x.Item2 == outputSenderData), outputReceiverData)); } else { int targetPort = curriedNode.Inputs.First( x => x.InnerNodeInputSender == outputSenderNode) .OuterNodeInPortData; int targetPortIndex = curriedNode.OuterNodePortDataList.IndexOf(targetPort); //Connect it (new dynConnector) newNodeWorkspace.AddConnection( outputSenderNode, curriedNode.InnerNode, outputSenderData, targetPortIndex + 1); } } } else { foreach (var hanging in selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count) .Where(port => !node.HasOutput(port)) .Select(port => new { node, port })).Distinct()) { //Create Symbol Node var node = newNodeWorkspace.AddNode<Output>(); node.Symbol = hanging.node.OutPortData[hanging.port].NickName; node.SetNickNameFromAttribute(); //store the element in the elements list node.DisableReporting(); node.X = rightMost + 75 - leftShift; node.Y = i*(50 + node.Height); newNodeWorkspace.AddConnection(hanging.node, node, hanging.port, 0); i++; } } #endregion // save and load the definition from file newNodeDefinition.SyncWithWorkspace(dynamoModel, true, true); dynamoModel.Workspaces.Add(newNodeWorkspace); string name = newNodeDefinition.FunctionId.ToString(); var collapsedNode = currentWorkspace.AddNode(avgX, avgY, name); undoRecorder.RecordCreationForUndo(collapsedNode); // place the node as intended, not centered collapsedNode.X = avgX; collapsedNode.Y = avgY; collapsedNode.DisableReporting(); foreach ( var nodeTuple in inConnectors.Select( (x, idx) => new { node = x.Item1, from = x.Item2, to = idx })) { var conn = currentWorkspace.AddConnection( nodeTuple.node, collapsedNode, nodeTuple.from, nodeTuple.to); if (conn != null) { undoRecorder.RecordCreationForUndo(conn); } } foreach (var nodeTuple in outConnectors) { var conn = currentWorkspace.AddConnection( collapsedNode, nodeTuple.Item1, nodeTuple.Item2, nodeTuple.Item3); if (conn != null) { undoRecorder.RecordCreationForUndo(conn); } } collapsedNode.EnableReporting(); currentWorkspace.EnableReporting(); foreach (var node in newNodeWorkspace.Nodes) node.EnableReporting(); newNodeWorkspace.WatchChanges = true; } }
/// <summary> /// Collapse a set of nodes in a given workspace. Has the side effects of prompting the user /// first in order to obtain the name and category for the new node, /// writes the function to a dyf file, adds it to the FunctionDict, adds it to search, and compiles and /// places the newly created symbol (defining a lambda) in the Controller's FScheme Environment. /// </summary> /// <param name="selectedNodes"> The function definition for the user-defined node </param> /// <param name="currentWorkspace"> The workspace where</param> internal static void Collapse(IEnumerable<dynNode> selectedNodes, dynWorkspace currentWorkspace) { var selectedNodeSet = new HashSet<dynNode>(selectedNodes); // TODO: this code needs refactoring #region Prompt //First, prompt the user to enter a name string newNodeName, newNodeCategory; string error = ""; do { var dialog = new FunctionNamePrompt(dynSettings.Controller.SearchViewModel.Categories, error); if (dialog.ShowDialog() != true) { return; } newNodeName = dialog.Text; newNodeCategory = dialog.Category; if (dynSettings.Controller.CustomNodeLoader.Contains(newNodeName)) { error = "A function with this name already exists."; } else if (newNodeCategory.Equals("")) { error = "Please enter a valid category."; } else { error = ""; } } while (!error.Equals("")); var newNodeWorkspace = new FuncWorkspace(newNodeName, newNodeCategory, 0, 0); var newNodeDefinition = new FunctionDefinition(Guid.NewGuid()); newNodeDefinition.Workspace = newNodeWorkspace; #endregion currentWorkspace.DisableReporting(); #region Determine Inputs and Outputs //Step 1: determine which nodes will be inputs to the new node var inputs = new HashSet<Tuple<dynNode, int, Tuple<int, dynNode>>>( selectedNodeSet .SelectMany(node => Enumerable.Range(0, node.InPortData.Count) .Where(node.HasInput) .Select(data => Tuple.Create(node, data, node.Inputs[data])) .Where(input => !selectedNodeSet.Contains(input.Item3.Item2)))); var outputs = new HashSet<Tuple<dynNode, int, Tuple<int, dynNode>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count).Where(node.HasOutput).SelectMany( data => node.Outputs[data] .Where(output => !selectedNodeSet.Contains(output.Item2)) .Select(output => Tuple.Create(node, data, output))))); #endregion #region Detect 1-node holes (higher-order function extraction) var curriedNodeArgs = new HashSet<dynNode>( inputs .Select(x => x.Item3.Item2) .Intersect(outputs.Select(x => x.Item3.Item2))) .Select( outerNode => { var node = new dynApply1(); dynNodeUI nodeUI = node.NodeUI; var elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), true)[0] as NodeNameAttribute; if (elNameAttrib != null) { nodeUI.NickName = elNameAttrib.Name; } nodeUI.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); dynSettings.Bench.WorkBench.Children.Add(nodeUI); //Place it in an appropriate spot Canvas.SetLeft(nodeUI, Canvas.GetLeft(outerNode.NodeUI)); Canvas.SetTop(nodeUI, Canvas.GetTop(outerNode.NodeUI)); //Fetch all input ports // in order // that have inputs // and whose input comes from an inner node List<int> inPortsConnected = Enumerable.Range(0, outerNode.InPortData.Count) .Where( x => outerNode.HasInput(x) && selectedNodeSet.Contains( outerNode.Inputs[x].Item2)) .ToList(); var nodeInputs = outputs .Where(output => output.Item3.Item2 == outerNode) .Select( output => new { InnerNodeInputSender = output.Item1, OuterNodeInPortData = output.Item3.Item1 }).ToList(); nodeInputs.ForEach(_ => node.AddInput()); node.NodeUI.RegisterAllPorts(); dynSettings.Bench.WorkBench.UpdateLayout(); return new { OuterNode = outerNode, InnerNode = node, Outputs = inputs.Where(input => input.Item3.Item2 == outerNode) .Select(input => input.Item3.Item1), Inputs = nodeInputs, OuterNodePortDataList = inPortsConnected }; }).ToList(); #endregion #region UI Positioning Calculations double avgX = selectedNodeSet.Average(node => Canvas.GetLeft(node.NodeUI)); double avgY = selectedNodeSet.Average(node => Canvas.GetTop(node.NodeUI)); double leftMost = selectedNodeSet.Min(node => Canvas.GetLeft(node.NodeUI)) + 24; double topMost = selectedNodeSet.Min(node => Canvas.GetTop(node.NodeUI)); double rightMost = selectedNodeSet.Max(node => Canvas.GetLeft(node.NodeUI) + node.NodeUI.Width); #endregion #region Move selection to new workspace var connectors = new HashSet<dynConnector>( currentWorkspace.Connectors.Where( conn => selectedNodeSet.Contains(conn.Start.Owner.NodeLogic) && selectedNodeSet.Contains(conn.End.Owner.NodeLogic))); //Step 2: move all nodes to new workspace // remove from old currentWorkspace.Nodes.RemoveAll(selectedNodeSet.Contains); currentWorkspace.Connectors.RemoveAll(connectors.Contains); // add to new newNodeWorkspace.Nodes.AddRange(selectedNodeSet); newNodeWorkspace.Connectors.AddRange(connectors); double leftShift = leftMost - 250; foreach (dynNodeUI node in newNodeWorkspace.Nodes.Select(x => x.NodeUI)) { Canvas.SetLeft(node, Canvas.GetLeft(node) - leftShift); Canvas.SetTop(node, Canvas.GetTop(node) - topMost + 120); } #endregion #region Insert new node into the current workspace //Step 5: insert new node into original workspace var collapsedNode = new dynFunction( inputs.Select(x => x.Item1.InPortData[x.Item2].NickName), outputs .Where(x => !curriedNodeArgs.Any(y => y.OuterNode == x.Item3.Item2)) .Select(x => x.Item1.OutPortData[x.Item2].NickName), newNodeDefinition); collapsedNode.NodeUI.GUID = Guid.NewGuid(); currentWorkspace.Nodes.Add(collapsedNode); collapsedNode.WorkSpace = currentWorkspace; dynSettings.Bench.WorkBench.Children.Add(collapsedNode.NodeUI); Canvas.SetLeft(collapsedNode.NodeUI, avgX); Canvas.SetTop(collapsedNode.NodeUI, avgY); #endregion #region Destroy all hanging connectors //Step 6: connect inputs and outputs foreach (dynConnector connector in currentWorkspace.Connectors .Where( c => selectedNodeSet.Contains(c.Start.Owner.NodeLogic) && !selectedNodeSet.Contains(c.End.Owner.NodeLogic)) .ToList()) { connector.Kill(); } foreach (dynConnector connector in currentWorkspace.Connectors .Where( c => !selectedNodeSet.Contains(c.Start.Owner.NodeLogic) && selectedNodeSet.Contains(c.End.Owner.NodeLogic)).ToList() ) { connector.Kill(); } #endregion newNodeWorkspace.Nodes.ForEach(x => x.DisableReporting()); var inConnectors = new List<Tuple<dynNodeUI, int, int>>(); #region Process inputs //Step 3: insert variables (reference step 1) foreach (var input in Enumerable.Range(0, inputs.Count).Zip(inputs, Tuple.Create)) { int inputIndex = input.Item1; dynNode inputReceiverNode = input.Item2.Item1; int inputReceiverData = input.Item2.Item2; dynNode inputNode = input.Item2.Item3.Item2; int inputData = input.Item2.Item3.Item1; inConnectors.Add(new Tuple<dynNodeUI, int, int>(inputNode.NodeUI, inputData, inputIndex)); //Create Symbol Node var node = new dynSymbol { Symbol = inputReceiverNode.InPortData[inputReceiverData].NickName }; dynNodeUI nodeUI = node.NodeUI; var elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), true)[0] as NodeNameAttribute; if (elNameAttrib != null) { nodeUI.NickName = elNameAttrib.Name; } nodeUI.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); dynSettings.Bench.WorkBench.Children.Add(nodeUI); //Place it in an appropriate spot Canvas.SetLeft(nodeUI, 0); Canvas.SetTop(nodeUI, inputIndex * (50 + node.NodeUI.Height)); dynSettings.Bench.WorkBench.UpdateLayout(); var curriedNode = curriedNodeArgs.FirstOrDefault( x => x.OuterNode == inputNode); if (curriedNode == null) { //Connect it (new dynConnector) newNodeWorkspace.Connectors.Add(new dynConnector( nodeUI, inputReceiverNode.NodeUI, 0, inputReceiverData, 0, false)); } else { //Connect it to the applier newNodeWorkspace.Connectors.Add(new dynConnector( nodeUI, curriedNode.InnerNode.NodeUI, 0, 0, 0, false)); //Connect applier to the inner input receiver newNodeWorkspace.Connectors.Add(new dynConnector( curriedNode.InnerNode.NodeUI, inputReceiverNode.NodeUI, 0, inputReceiverData, 0, false)); } } #endregion #region Process outputs //List of all inner nodes to connect an output. Unique. var outportList = new List<Tuple<dynNode, int>>(); var outConnectors = new List<Tuple<dynNodeUI, int, int>>(); int i = 0; foreach (var output in outputs) { if (outportList.All(x => !(x.Item1 == output.Item1 && x.Item2 == output.Item2))) { dynNode outputSenderNode = output.Item1; int outputSenderData = output.Item2; dynNode outputReceiverNode = output.Item3.Item2; if (curriedNodeArgs.Any(x => x.OuterNode == outputReceiverNode)) continue; outportList.Add(Tuple.Create(outputSenderNode, outputSenderData)); //Create Symbol Node var node = new dynOutput { Symbol = outputSenderNode.OutPortData[outputSenderData].NickName }; dynNodeUI nodeUI = node.NodeUI; var elNameAttrib = node.GetType().GetCustomAttributes(typeof(NodeNameAttribute), false)[0] as NodeNameAttribute; if (elNameAttrib != null) { nodeUI.NickName = elNameAttrib.Name; } nodeUI.GUID = Guid.NewGuid(); //store the element in the elements list newNodeWorkspace.Nodes.Add(node); node.WorkSpace = newNodeWorkspace; node.DisableReporting(); dynSettings.Bench.WorkBench.Children.Add(nodeUI); //Place it in an appropriate spot Canvas.SetLeft(nodeUI, rightMost + 75 - leftShift); Canvas.SetTop(nodeUI, i * (50 + node.NodeUI.Height)); dynSettings.Bench.WorkBench.UpdateLayout(); newNodeWorkspace.Connectors.Add(new dynConnector( outputSenderNode.NodeUI, nodeUI, outputSenderData, 0, 0, false)); i++; } } //Connect outputs to new node foreach (var output in outputs) { //Node to be connected to in CurrentSpace dynNode outputSenderNode = output.Item1; //Port to be connected to on outPutNode_outer int outputSenderData = output.Item2; int outputReceiverData = output.Item3.Item1; dynNode outputReceiverNode = output.Item3.Item2; var curriedNode = curriedNodeArgs.FirstOrDefault( x => x.OuterNode == outputReceiverNode); if (curriedNode == null) { // we create the connectors in the current space later outConnectors.Add(new Tuple<dynNodeUI, int, int>(outputReceiverNode.NodeUI, outportList.FindIndex(x => x.Item1 == outputSenderNode && x.Item2 == outputSenderData), outputReceiverData)); } else { int targetPort = curriedNode.Inputs .First( x => x.InnerNodeInputSender == outputSenderNode) .OuterNodeInPortData; int targetPortIndex = curriedNode.OuterNodePortDataList.IndexOf(targetPort); //Connect it (new dynConnector) newNodeWorkspace.Connectors.Add(new dynConnector( outputSenderNode.NodeUI, curriedNode.InnerNode.NodeUI, outputSenderData, targetPortIndex + 1, 0)); } } #endregion #region Make new workspace invisible //Step 4: make nodes invisible // and update positions foreach (dynNodeUI node in newNodeWorkspace.Nodes.Select(x => x.NodeUI)) node.Visibility = Visibility.Hidden; foreach (dynConnector connector in newNodeWorkspace.Connectors) connector.Visible = false; #endregion //set the name on the node collapsedNode.NodeUI.NickName = newNodeName; currentWorkspace.Nodes.Remove(collapsedNode); dynSettings.Bench.WorkBench.Children.Remove(collapsedNode.NodeUI); // save and load the definition from file var path = dynSettings.Controller.SaveFunctionOnly(newNodeDefinition); dynSettings.Controller.CustomNodeLoader.SetNodeInfo(newNodeName, newNodeCategory, newNodeDefinition.FunctionId, path); dynSettings.Controller.SearchViewModel.Add(newNodeName, newNodeCategory, newNodeDefinition.FunctionId); DynamoCommands.CreateNodeCmd.Execute(new Dictionary<string, object>() { {"name", collapsedNode.Definition.FunctionId.ToString() }, {"x", avgX }, {"y", avgY } }); var newlyPlacedCollapsedNode = currentWorkspace.Nodes .Where(node => node is dynFunction) .First(node => ((dynFunction)node).Definition.FunctionId == newNodeDefinition.FunctionId); newlyPlacedCollapsedNode.DisableReporting(); dynSettings.Bench.WorkBench.UpdateLayout(); // without doing this, connectors fail to be created foreach (var nodeTuple in inConnectors) { currentWorkspace.Connectors.Add( new dynConnector( nodeTuple.Item1, newlyPlacedCollapsedNode.NodeUI, nodeTuple.Item2, nodeTuple.Item3, 0, true)); } foreach (var nodeTuple in outConnectors) { currentWorkspace.Connectors.Add( new dynConnector( newlyPlacedCollapsedNode.NodeUI, nodeTuple.Item1, nodeTuple.Item2, nodeTuple.Item3, 0, true)); } newlyPlacedCollapsedNode.EnableReporting(); currentWorkspace.EnableReporting(); }
private static Graph KruskalB(Graph graph) { HashSet<Vertex> inTree = new HashSet<Vertex>(); Graph mst = graph.Clone(); foreach (var edge in mst.Edges) mst.RemoveEdge(edge); // Start with one random vertex inTree.Add(graph.Vertices[0]); while (mst.NumberOfEdges < graph.NumberOfVertices - 1) { // Find new edge to add to the tree. var candidateEdges = inTree.SelectMany(graph.GetEdgesForVertex).ToList(); candidateEdges.Sort((x, y) => x.Cost.CompareTo(y.Cost)); // Sort from cheap to expensive foreach (var edge in candidateEdges) { var v1 = edge.Either(); var v2 = edge.Other(v1); bool v1InTree = inTree.Contains(v1); bool v2InTree = inTree.Contains(v2); if (v1InTree ^ v2InTree) // The ^ is a XOR { // One side of this edge is in the MST, the other is not mst.AddEdge(edge); inTree.Add(v1); inTree.Add(v2); break; } } } return mst; }
/// <summary> /// Collapse a set of nodes in a given workspace. /// </summary> /// <param name="selectedNodes"> The function definition for the user-defined node </param> /// <param name="currentWorkspace"> The workspace where</param> /// <param name="isTestMode"></param> /// <param name="args"></param> public CustomNodeWorkspaceModel Collapse( IEnumerable<NodeModel> selectedNodes, WorkspaceModel currentWorkspace, bool isTestMode, FunctionNamePromptEventArgs args) { var selectedNodeSet = new HashSet<NodeModel>(selectedNodes); // Note that undoable actions are only recorded for the "currentWorkspace", // the nodes which get moved into "newNodeWorkspace" are not recorded for undo, // even in the new workspace. Their creations will simply be treated as part of // the opening of that new workspace (i.e. when a user opens a file, she will // not expect the nodes that show up to be undoable). // // After local nodes are moved into "newNodeWorkspace" as the result of // conversion, if user performs an undo, new set of nodes will be created in // "currentWorkspace" (not moving those nodes in the "newNodeWorkspace" back // into "currentWorkspace"). In another word, undo recording is on a per- // workspace basis, it does not work across different workspaces. // UndoRedoRecorder undoRecorder = currentWorkspace.UndoRecorder; CustomNodeWorkspaceModel newWorkspace; using (undoRecorder.BeginActionGroup()) { #region Determine Inputs and Outputs //Step 1: determine which nodes will be inputs to the new node var inputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.InPortData.Count) .Where(node.HasConnectedInput) .Select(data => Tuple.Create(node, data, node.InputNodes[data])) .Where(input => !selectedNodeSet.Contains(input.Item3.Item2)))); var outputs = new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>( selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count) .Where(node.HasOutput) .SelectMany( data => node.OutputNodes[data].Where( output => !selectedNodeSet.Contains(output.Item2)) .Select(output => Tuple.Create(node, data, output))))); #endregion #region Detect 1-node holes (higher-order function extraction) Log(Properties.Resources.CouldNotRepairOneNodeHoles, WarningLevel.Mild); // http://adsk-oss.myjetbrains.com/youtrack/issue/MAGN-5603 //var curriedNodeArgs = // new HashSet<NodeModel>( // inputs.Select(x => x.Item3.Item2) // .Intersect(outputs.Select(x => x.Item3.Item2))).Select( // outerNode => // { // //var node = new Apply1(); // var node = newNodeWorkspace.AddNode<Apply1>(); // node.SetNickNameFromAttribute(); // node.DisableReporting(); // node.X = outerNode.X; // node.Y = outerNode.Y; // //Fetch all input ports // // in order // // that have inputs // // and whose input comes from an inner node // List<int> inPortsConnected = // Enumerable.Range(0, outerNode.InPortData.Count) // .Where( // x => // outerNode.HasInput(x) // && selectedNodeSet.Contains( // outerNode.Inputs[x].Item2)) // .ToList(); // var nodeInputs = // outputs.Where(output => output.Item3.Item2 == outerNode) // .Select( // output => // new // { // InnerNodeInputSender = output.Item1, // OuterNodeInPortData = output.Item3.Item1 // }) // .ToList(); // nodeInputs.ForEach(_ => node.AddInput()); // node.RegisterAllPorts(); // return // new // { // OuterNode = outerNode, // InnerNode = node, // Outputs = // inputs.Where( // input => input.Item3.Item2 == outerNode) // .Select(input => input.Item3.Item1), // Inputs = nodeInputs, // OuterNodePortDataList = inPortsConnected // }; // }).ToList(); #endregion #region UI Positioning Calculations double avgX = selectedNodeSet.Average(node => node.X); double avgY = selectedNodeSet.Average(node => node.Y); double leftMost = selectedNodeSet.Min(node => node.X); double topMost = selectedNodeSet.Min(node => node.Y); double rightMost = selectedNodeSet.Max(node => node.X + node.Width); double leftShift = leftMost - 250; #endregion #region Handle full selected connectors // Step 2: Determine all the connectors whose start/end owners are // both in the selection set, and then move them from the current // workspace into the new workspace. var fullySelectedConns = new HashSet<ConnectorModel>( currentWorkspace.Connectors.Where( conn => { bool startSelected = selectedNodeSet.Contains(conn.Start.Owner); bool endSelected = selectedNodeSet.Contains(conn.End.Owner); return startSelected && endSelected; })); foreach (var connector in fullySelectedConns) { undoRecorder.RecordDeletionForUndo(connector); connector.Delete(); } #endregion #region Handle partially selected connectors // Step 3: Partially selected connectors (either one of its start // and end owners is in the selection) are to be destroyed. var partiallySelectedConns = currentWorkspace.Connectors.Where( conn => selectedNodeSet.Contains(conn.Start.Owner) || selectedNodeSet.Contains(conn.End.Owner)).ToList(); foreach (var connector in partiallySelectedConns) { undoRecorder.RecordDeletionForUndo(connector); connector.Delete(); } #endregion #region Transfer nodes and connectors to new workspace var newNodes = new List<NodeModel>(); var newAnnotations = new List<AnnotationModel>(); // Step 4: move all nodes to new workspace remove from old // PB: This could be more efficiently handled by a copy paste, but we // are preservering the node foreach (var node in selectedNodeSet) { undoRecorder.RecordDeletionForUndo(node); currentWorkspace.RemoveNode(node); // Assign a new guid to this node, otherwise when node is // compiled to AST, literally it is still in global scope // instead of in function scope. node.GUID = Guid.NewGuid(); node.RenderPackages.Clear(); // shift nodes node.X = node.X - leftShift; node.Y = node.Y - topMost; newNodes.Add(node); } //Copy the group from newNodes foreach (var group in DynamoSelection.Instance.Selection.OfType<AnnotationModel>()) { undoRecorder.RecordDeletionForUndo(group); currentWorkspace.RemoveGroup(group); group.GUID = Guid.NewGuid(); group.SelectedModels = group.DeletedModelBases; newAnnotations.Add(group); } foreach (var conn in fullySelectedConns) { ConnectorModel.Make(conn.Start.Owner, conn.End.Owner, conn.Start.Index, conn.End.Index); } #endregion #region Process inputs var inConnectors = new List<Tuple<NodeModel, int>>(); var uniqueInputSenders = new Dictionary<Tuple<NodeModel, int>, Symbol>(); //Step 3: insert variables (reference step 1) foreach (var input in Enumerable.Range(0, inputs.Count).Zip(inputs, Tuple.Create)) { int inputIndex = input.Item1; NodeModel inputReceiverNode = input.Item2.Item1; int inputReceiverData = input.Item2.Item2; NodeModel inputNode = input.Item2.Item3.Item2; int inputData = input.Item2.Item3.Item1; Symbol node; var key = Tuple.Create(inputNode, inputData); if (uniqueInputSenders.ContainsKey(key)) { node = uniqueInputSenders[key]; } else { inConnectors.Add(Tuple.Create(inputNode, inputData)); node = new Symbol { InputSymbol = inputReceiverNode.InPortData[inputReceiverData].NickName, X = 0 }; // Try to figure out the type of input of custom node // from the type of input of selected node. There are // two kinds of nodes whose input type are available: // function node and custom node. List<Library.TypedParameter> parameters = null; if (inputReceiverNode is Function) { var func = inputReceiverNode as Function; parameters = func.Controller.Definition.Parameters.ToList(); } else if (inputReceiverNode is DSFunctionBase) { var dsFunc = inputReceiverNode as DSFunctionBase; var funcDesc = dsFunc.Controller.Definition; parameters = funcDesc.Parameters.ToList(); if (funcDesc.Type == DSEngine.FunctionType.InstanceMethod || funcDesc.Type == DSEngine.FunctionType.InstanceProperty) { var dummyType = new ProtoCore.Type() { Name = funcDesc.ClassName }; var instanceParam = new TypedParameter(funcDesc.ClassName, dummyType); parameters.Insert(0, instanceParam); } } // so the input of custom node has format // input_var_name : type if (parameters != null && parameters.Count() > inputReceiverData) { var typeName = parameters[inputReceiverData].DisplayTypeName; if (!string.IsNullOrEmpty(typeName)) { node.InputSymbol += " : " + typeName; } } node.SetNickNameFromAttribute(); node.Y = inputIndex*(50 + node.Height); uniqueInputSenders[key] = node; newNodes.Add(node); } //var curriedNode = curriedNodeArgs.FirstOrDefault(x => x.OuterNode == inputNode); //if (curriedNode == null) //{ ConnectorModel.Make(node, inputReceiverNode, 0, inputReceiverData); //} //else //{ // //Connect it to the applier // newNodeWorkspace.AddConnection(node, curriedNode.InnerNode, 0, 0); // //Connect applier to the inner input receive // newNodeWorkspace.AddConnection( // curriedNode.InnerNode, // inputReceiverNode, // 0, // inputReceiverData); //} } #endregion #region Process outputs //List of all inner nodes to connect an output. Unique. var outportList = new List<Tuple<NodeModel, int>>(); var outConnectors = new List<Tuple<NodeModel, int, int>>(); int i = 0; if (outputs.Any()) { foreach (var output in outputs) { if (outportList.All(x => !(x.Item1 == output.Item1 && x.Item2 == output.Item2))) { NodeModel outputSenderNode = output.Item1; int outputSenderData = output.Item2; //NodeModel outputReceiverNode = output.Item3.Item2; //if (curriedNodeArgs.Any(x => x.OuterNode == outputReceiverNode)) // continue; outportList.Add(Tuple.Create(outputSenderNode, outputSenderData)); //Create Symbol Node var node = new Output { Symbol = outputSenderNode.OutPortData[outputSenderData].NickName, X = rightMost + 75 - leftShift }; node.Y = i*(50 + node.Height); node.SetNickNameFromAttribute(); newNodes.Add(node); ConnectorModel.Make(outputSenderNode, node, outputSenderData, 0); i++; } } //Connect outputs to new node outConnectors.AddRange( from output in outputs let outputSenderNode = output.Item1 let outputSenderData = output.Item2 let outputReceiverData = output.Item3.Item1 let outputReceiverNode = output.Item3.Item2 select Tuple.Create( outputReceiverNode, outportList.FindIndex( x => x.Item1 == outputSenderNode && x.Item2 == outputSenderData), outputReceiverData)); } else { foreach (var hanging in selectedNodeSet.SelectMany( node => Enumerable.Range(0, node.OutPortData.Count) .Where(port => !node.HasOutput(port)) .Select(port => new { node, port })).Distinct()) { //Create Symbol Node var node = new Output { Symbol = hanging.node.OutPortData[hanging.port].NickName, X = rightMost + 75 - leftShift }; node.Y = i*(50 + node.Height); node.SetNickNameFromAttribute(); newNodes.Add(node); ConnectorModel.Make(hanging.node, node, hanging.port, 0); i++; } } #endregion var newId = Guid.NewGuid(); newWorkspace = new CustomNodeWorkspaceModel( nodeFactory, newNodes, Enumerable.Empty<NoteModel>(), newAnnotations, Enumerable.Empty<PresetModel>(), new WorkspaceInfo() { X = 0, Y = 0, Name = args.Name, Category = args.Category, Description = args.Description, ID = newId.ToString(), FileName = string.Empty }, currentWorkspace.ElementResolver); newWorkspace.HasUnsavedChanges = true; RegisterCustomNodeWorkspace(newWorkspace); var collapsedNode = CreateCustomNodeInstance(newId, isTestMode: isTestMode); collapsedNode.X = avgX; collapsedNode.Y = avgY; currentWorkspace.AddNode(collapsedNode, centered: false); undoRecorder.RecordCreationForUndo(collapsedNode); foreach (var connector in inConnectors.Select((x, idx) => new { node = x.Item1, from = x.Item2, to = idx }) .Select( nodeTuple => ConnectorModel.Make( nodeTuple.node, collapsedNode, nodeTuple.@from, nodeTuple.to)) .Where(connector => connector != null)) { undoRecorder.RecordCreationForUndo(connector); } foreach (var connector in outConnectors.Select( nodeTuple => ConnectorModel.Make( collapsedNode, nodeTuple.Item1, nodeTuple.Item2, nodeTuple.Item3)).Where(connector => connector != null)) { undoRecorder.RecordCreationForUndo(connector); } } return newWorkspace; }
/// <summary> /// Main entry point for the BuildGraph command /// </summary> public override ExitCode Execute() { // Parse the command line parameters string ScriptFileName = ParseParamValue("Script", null); string TargetNames = ParseParamValue("Target", null); string DocumentationFileName = ParseParamValue("Documentation", null); string SchemaFileName = ParseParamValue("Schema", null); string ExportFileName = ParseParamValue("Export", null); string PreprocessedFileName = ParseParamValue("Preprocess", null); string SharedStorageDir = ParseParamValue("SharedStorageDir", null); string SingleNodeName = ParseParamValue("SingleNode", null); string TriggerName = ParseParamValue("Trigger", null); string[] SkipTriggerNames = ParseParamValue("SkipTrigger", "").Split(new char[]{ '+', ';' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); bool bSkipTriggers = ParseParam("SkipTriggers"); string TokenSignature = ParseParamValue("TokenSignature", null); bool bSkipTargetsWithoutTokens = ParseParam("SkipTargetsWithoutTokens"); bool bClearHistory = ParseParam("Clean") || ParseParam("ClearHistory"); bool bListOnly = ParseParam("ListOnly"); bool bWriteToSharedStorage = ParseParam("WriteToSharedStorage") || CommandUtils.IsBuildMachine; bool bPublicTasksOnly = ParseParam("PublicTasksOnly"); string ReportName = ParseParamValue("ReportName", null); GraphPrintOptions PrintOptions = GraphPrintOptions.ShowCommandLineOptions; if(ParseParam("ShowDeps")) { PrintOptions |= GraphPrintOptions.ShowDependencies; } if(ParseParam("ShowNotifications")) { PrintOptions |= GraphPrintOptions.ShowNotifications; } // Parse any specific nodes to clean List<string> CleanNodes = new List<string>(); foreach(string NodeList in ParseParamValues("CleanNode")) { foreach(string NodeName in NodeList.Split('+', ';')) { CleanNodes.Add(NodeName); } } // Set up the standard properties which build scripts might need Dictionary<string, string> DefaultProperties = new Dictionary<string,string>(StringComparer.InvariantCultureIgnoreCase); DefaultProperties["Branch"] = P4Enabled ? P4Env.BuildRootP4 : "Unknown"; DefaultProperties["EscapedBranch"] = P4Enabled ? P4Env.BuildRootEscaped : "Unknown"; DefaultProperties["Change"] = P4Enabled ? P4Env.Changelist.ToString() : "0"; DefaultProperties["CodeChange"] = P4Enabled ? P4Env.CodeChangelist.ToString() : "0"; DefaultProperties["RootDir"] = CommandUtils.RootDirectory.FullName; DefaultProperties["IsBuildMachine"] = IsBuildMachine ? "true" : "false"; DefaultProperties["HostPlatform"] = HostPlatform.Current.HostEditorPlatform.ToString(); // Attempt to read existing Build Version information BuildVersion Version; if (BuildVersion.TryRead(FileReference.Combine(CommandUtils.RootDirectory, "Engine", "Build", "Build.version").FullName, out Version)) { DefaultProperties["EngineMajorVersion"] = Version.MajorVersion.ToString(); DefaultProperties["EngineMinorVersion"] = Version.MinorVersion.ToString(); DefaultProperties["EnginePatchVersion"] = Version.PatchVersion.ToString(); } // Add any additional custom arguments from the command line (of the form -Set:X=Y) Dictionary<string, string> Arguments = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); foreach (string Param in Params) { const string Prefix = "set:"; if(Param.StartsWith(Prefix, StringComparison.InvariantCultureIgnoreCase)) { int EqualsIdx = Param.IndexOf('='); if(EqualsIdx >= 0) { Arguments[Param.Substring(Prefix.Length, EqualsIdx - Prefix.Length)] = Param.Substring(EqualsIdx + 1); } else { LogWarning("Missing value for '{0}'", Param.Substring(Prefix.Length)); } } } // Find all the tasks from the loaded assemblies Dictionary<string, ScriptTask> NameToTask = new Dictionary<string,ScriptTask>(); if(!FindAvailableTasks(NameToTask, bPublicTasksOnly)) { return ExitCode.Error_Unknown; } // Generate documentation if(DocumentationFileName != null) { GenerateDocumentation(NameToTask, new FileReference(DocumentationFileName)); return ExitCode.Success; } // Create a schema for the given tasks ScriptSchema Schema = new ScriptSchema(NameToTask); if(SchemaFileName != null) { FileReference FullSchemaFileName = new FileReference(SchemaFileName); Log("Writing schema to {0}...", FullSchemaFileName.FullName); Schema.Export(FullSchemaFileName); if(ScriptFileName == null) { return ExitCode.Success; } } // Check there was a script specified if(ScriptFileName == null) { LogError("Missing -Script= parameter for BuildGraph"); return ExitCode.Error_Unknown; } // Read the script from disk Graph Graph; if(!ScriptReader.TryRead(new FileReference(ScriptFileName), Arguments, DefaultProperties, Schema, out Graph)) { return ExitCode.Error_Unknown; } // Create the temp storage handler DirectoryReference RootDir = new DirectoryReference(CommandUtils.CmdEnv.LocalRoot); TempStorage Storage = new TempStorage(RootDir, DirectoryReference.Combine(RootDir, "Engine", "Saved", "BuildGraph"), (SharedStorageDir == null)? null : new DirectoryReference(SharedStorageDir), bWriteToSharedStorage); if(bClearHistory) { Storage.CleanLocal(); } foreach(string CleanNode in CleanNodes) { Storage.CleanLocalNode(CleanNode); } // Convert the supplied target references into nodes HashSet<Node> TargetNodes = new HashSet<Node>(); if(TargetNames == null) { if(!bListOnly) { LogError("Missing -Target= parameter for BuildGraph"); return ExitCode.Error_Unknown; } TargetNodes.UnionWith(Graph.Agents.SelectMany(x => x.Nodes)); } else { foreach(string TargetName in TargetNames.Split(new char[]{ '+', ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim())) { Node[] Nodes; if(!Graph.TryResolveReference(TargetName, out Nodes)) { LogError("Target '{0}' is not in graph", TargetName); return ExitCode.Error_Unknown; } TargetNodes.UnionWith(Nodes); } } // Try to acquire tokens for all the target nodes we want to build if(TokenSignature != null) { // Find all the lock files HashSet<FileReference> RequiredTokens = new HashSet<FileReference>(TargetNodes.SelectMany(x => x.RequiredTokens)); // List out all the required tokens if(SingleNodeName == null) { CommandUtils.Log("Required tokens:"); foreach(Node Node in TargetNodes) { foreach(FileReference RequiredToken in Node.RequiredTokens) { CommandUtils.Log(" '{0}' requires {1}", Node, RequiredToken); } } } // Try to create all the lock files List<FileReference> CreatedTokens = new List<FileReference>(); if(!bListOnly) { CreatedTokens.AddRange(RequiredTokens.Where(x => WriteTokenFile(x, TokenSignature))); } // Find all the tokens that we don't have Dictionary<FileReference, string> MissingTokens = new Dictionary<FileReference, string>(); foreach(FileReference RequiredToken in RequiredTokens) { string CurrentOwner = ReadTokenFile(RequiredToken); if(CurrentOwner != null && CurrentOwner != TokenSignature) { MissingTokens.Add(RequiredToken, CurrentOwner); } } // If we want to skip all the nodes with missing locks, adjust the target nodes to account for it if(MissingTokens.Count > 0) { if(bSkipTargetsWithoutTokens) { // Find all the nodes we're going to skip HashSet<Node> SkipNodes = new HashSet<Node>(); foreach(IGrouping<string, FileReference> MissingTokensForBuild in MissingTokens.GroupBy(x => x.Value, x => x.Key)) { Log("Skipping the following nodes due to {0}:", MissingTokensForBuild.Key); foreach(FileReference MissingToken in MissingTokensForBuild) { foreach(Node SkipNode in TargetNodes.Where(x => x.RequiredTokens.Contains(MissingToken) && SkipNodes.Add(x))) { Log(" {0}", SkipNode); } } } // Write a list of everything left over if(SkipNodes.Count > 0) { TargetNodes.ExceptWith(SkipNodes); Log("Remaining target nodes:"); foreach(Node TargetNode in TargetNodes) { Log(" {0}", TargetNode); } if(TargetNodes.Count == 0) { Log(" None."); } } } else { foreach(KeyValuePair<FileReference, string> Pair in MissingTokens) { List<Node> SkipNodes = TargetNodes.Where(x => x.RequiredTokens.Contains(Pair.Key)).ToList(); LogError("Cannot run {0} due to previous build: {1}", String.Join(", ", SkipNodes), Pair.Value); } foreach(FileReference CreatedToken in CreatedTokens) { CreatedToken.Delete(); } return ExitCode.Error_Unknown; } } } // Cull the graph to include only those nodes Graph.Select(TargetNodes); // Collapse any triggers in the graph which are marked to be skipped HashSet<ManualTrigger> SkipTriggers = new HashSet<ManualTrigger>(); if(bSkipTriggers) { SkipTriggers.UnionWith(Graph.NameToTrigger.Values); } else { foreach(string SkipTriggerName in SkipTriggerNames) { ManualTrigger SkipTrigger; if(!Graph.NameToTrigger.TryGetValue(TriggerName, out SkipTrigger)) { LogError("Couldn't find trigger '{0}'", TriggerName); return ExitCode.Error_Unknown; } SkipTriggers.Add(SkipTrigger); } } Graph.SkipTriggers(SkipTriggers); // If a report for the whole build was requested, insert it into the graph if (ReportName != null) { Report NewReport = new Report(ReportName); NewReport.Nodes.UnionWith(Graph.Agents.SelectMany(x => x.Nodes)); Graph.NameToReport.Add(ReportName, NewReport); } // Write out the preprocessed script if (PreprocessedFileName != null) { Graph.Write(new FileReference(PreprocessedFileName), (SchemaFileName != null)? new FileReference(SchemaFileName) : null); } // Find the triggers which we are explicitly running. ManualTrigger Trigger = null; if(TriggerName != null && !Graph.NameToTrigger.TryGetValue(TriggerName, out Trigger)) { LogError("Couldn't find trigger '{0}'", TriggerName); return ExitCode.Error_Unknown; } // If we're just building a single node, find it Node SingleNode = null; if(SingleNodeName != null && !Graph.NameToNode.TryGetValue(SingleNodeName, out SingleNode)) { LogError("Node '{0}' is not in the trimmed graph", SingleNodeName); return ExitCode.Error_Unknown; } // If we just want to show the contents of the graph, do so and exit. if(bListOnly) { HashSet<Node> CompletedNodes = FindCompletedNodes(Graph, Storage); Graph.Print(CompletedNodes, PrintOptions); return ExitCode.Success; } // Print out all the diagnostic messages which still apply, unless we're running a step as part of a build system or just listing the contents of the file. if(SingleNode == null) { IEnumerable<GraphDiagnostic> Diagnostics = Graph.Diagnostics.Where(x => x.EnclosingTrigger == Trigger); foreach(GraphDiagnostic Diagnostic in Diagnostics) { if(Diagnostic.EventType == LogEventType.Warning) { CommandUtils.LogWarning(Diagnostic.Message); } else { CommandUtils.LogError(Diagnostic.Message); } } if(Diagnostics.Any(x => x.EventType == LogEventType.Error)) { return ExitCode.Error_Unknown; } } // Execute the command if(ExportFileName != null) { HashSet<Node> CompletedNodes = FindCompletedNodes(Graph, Storage); Graph.Print(CompletedNodes, PrintOptions); Graph.Export(new FileReference(ExportFileName), Trigger, CompletedNodes); } else if(SingleNode != null) { if(!BuildNode(new JobContext(this), Graph, SingleNode, Storage, bWithBanner: true)) { return ExitCode.Error_Unknown; } } else { if(!BuildAllNodes(new JobContext(this), Graph, Storage)) { return ExitCode.Error_Unknown; } } return ExitCode.Success; }
private IEnumerable<string> GetTransitiveClosure(string state) { var result = new HashSet<string> { state }; while (result.Union(result.SelectMany(s => GetTransitions(s, null))).Distinct().Count() != result.Count) { result.SelectMany(s => GetTransitions(s, null)).ToArray().ForEach(s => result.Add(s)); } return result; }