static void Main(string[] args) { int N = int.Parse(Console.ReadLine()); HashSet<House> Houses = new HashSet<House>(); long amountOfCable = 0; for (int i = 0; i < N; i++) { string[] inputs = Console.ReadLine().Split(' '); Houses.Add(new House { X = int.Parse(inputs[0]), Y = int.Parse(inputs[1]) }); } //Core: Calculate Average House Y index double Avg = Houses.Sum(x => x.Y) / N; //Core:find the house closest to the Avg Y and use its Y coordinate int closest = Houses.OrderBy(x => Math.Abs(x.Y - Avg)).First().Y; //lay the mainline amountOfCable += (Houses.Max(x => x.X) - Houses.Min(x => x.X)); //per other House calculate distance from location to mainline foreach (var i in Houses) { amountOfCable += i.Y > closest ? i.Y - closest : closest - i.Y; } // Write an action using Console.WriteLine() // To debug: Console.Error.WriteLine("Debug messages..."); Console.WriteLine(amountOfCable); }
HashSet<long> BuildOddComposites(HashSet<long> primes) { var oddComposites = new HashSet<long>(); for (int i = 33; i < primes.Max(); i+=2) { if (!primes.Contains(i)) oddComposites.Add(i); } return oddComposites; }
static void Main() { var collection = new HashSet<double> { 5.2, 8, -3.14, 0, 55 }; Console.WriteLine(collection.Sum()); Console.WriteLine(collection.Product()); Console.WriteLine(collection.Min()); Console.WriteLine(collection.Max()); Console.WriteLine(collection.Average()); }
public void FullRangeHit(Int32 maximum) { var rolls = new HashSet<Int32>(); while (LoopShouldStillRun() && rolls.Count < maximum) rolls.Add(Dice.Roll().d(maximum)); Assert.That(rolls.Min(), Is.EqualTo(1)); Assert.That(rolls.Max(), Is.EqualTo(maximum)); Assert.That(rolls.Count, Is.EqualTo(maximum)); Assert.Pass("Iterations: {0}", iterations); }
public override bool Execute() { if (Files == null || Files.Length == 0) { Log.LogError("Files argument must be specified"); return false; } // remove files that should be skipped or don't have a version var filesToConsider = Files.Where(f => !f.GetMetadata("SkipVersionCheck").Equals("true", StringComparison.OrdinalIgnoreCase) && !String.IsNullOrEmpty(f.GetMetadata("AssemblyVersion"))) .Select(f => new { File = f.ItemSpec, TargetPath = f.GetMetadata("TargetPath"), Version = new Version(f.GetMetadata("AssemblyVersion")) }); var refFiles = filesToConsider.Where(f => f.TargetPath.StartsWith("ref", StringComparison.OrdinalIgnoreCase)); HashSet<Version> permittedVersions = new HashSet<System.Version>(); if (refFiles.Any()) { foreach (var refFile in refFiles) { permittedVersions.Add(refFile.Version); } // use the version of the higest reference assembly; Version = refFiles.Max(f => f.Version).ToString(); } else { // no reference assemblies, permit any version foreach (var file in filesToConsider) { permittedVersions.Add(file.Version); } Version = permittedVersions.Max().ToString(); } foreach (var file in filesToConsider) { if (!permittedVersions.Contains(file.Version)) { Log.LogError("File {0} has version {1} which is inconsistent with other libs and doesn't match any reference assembly", file.File, file.Version); } } return !Log.HasLoggedErrors; }
public HotnessDetector(HashSet<double> allLatitudes, HashSet<double> allLongitudes) { // Get the entire list of waypoints within a single hunt // (or at least every latitude and longitude) // and determine the bounds of the playfield. // The playfield width is determined from the eastmost latitude // of the waypoints and the westmost latitude of the waypoints. // The playfield height is determined from the northernmost longitude // of the waypoints and the southernmost longitude of the waypoints. playfield = new GeoArea(allLongitudes.Min(), allLongitudes.Max(), allLatitudes.Max(), allLatitudes.Min()); }
public static uint Mex(HashSet<uint> set) { if (!set.Any()) return 0; //creepy implementation uint max = set.Max(), i = 0; for (; i <= max; i++) { if (!set.Contains(i)) break; } return i; }
public static void AddAnotherLocations(HashSet<Location> locs, int numberOfLocationsToAdd = 1) { var id = locs.Max(location => location.Id); for (int i = 0; i < numberOfLocationsToAdd; i++) { var longitude = 6 % (i + 1); var latitude = 6 % (i + 1); locs.Add(new Location ( latitude: latitude, longitude: longitude )); } }
static void Main(string[] args) { int p = int.Parse(Console.ReadLine()); string[] numbersStr = Console.ReadLine().Split(' '); HashSet <long> numbers = new HashSet <long>(); for (int k = 0; k < numbersStr.Length; k++) { numbers.Add(long.Parse(numbersStr[k])); } long max = numbers.Max(); resultsNumbers.Add(1); Recursion(max, 1, p); int[] result = new int[numbers.Count]; int i = 0; foreach (var number in numbers) { int counter = 0; foreach (var numInHashSet in resultsNumbers) { if (resultsNumbers.Contains(number - numInHashSet)) { counter++; } } if (counter == 2) { result[i] = 1; } else { result[i] = 0; } i++; } Console.WriteLine(string.Join(" ", result)); }
/// <summary> /// Call this to batch-optimize any object-changes notified through /// ssBVHNode.refit_ObjectChanged(..). For example, in a game-loop, /// call this once per frame. /// </summary> public void optimize() { if (LEAF_OBJ_MAX != 1) { throw new Exception("In order to use optimize, you must set LEAF_OBJ_MAX=1"); } while (refitNodes.Count > 0) { int maxdepth = refitNodes.Max(n => n.depth); var sweepNodes = refitNodes.Where(n => n.depth == maxdepth).ToList(); sweepNodes.ForEach(n => refitNodes.Remove(n)); sweepNodes.ForEach(n => n.tryRotate(this)); } }
public void Part2() { var parser = new Parser("Day05/Input.txt"); var lines = parser.Parse(new BoardingPassFactory()); var sut = new BoardingPassScanner(); var seats = new HashSet <int>(); foreach (var line in lines) { seats.Add(sut.Scan(line).SeatId()); } var actual = Enumerable.Range(seats.Min(), seats.Max()) .SkipWhile(s => seats.Contains(s)) .First(); Assert.Equal(731, actual); }
public static int Part2(string input) { var lines = input.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).ToList(); var layers = new HashSet <Layer>(); foreach (var line in lines) { var splits = line.Split(":", StringSplitOptions.RemoveEmptyEntries).ToList(); layers.Add(new Layer { ID = Int32.Parse(splits[0]), Range = Int32.Parse(splits[1]) }); } var maxLayer = layers.Max(l => l.ID); var delay = 0; bool successfulTrip = false; while (!successfulTrip) { bool hasBeenCaught = false; foreach (var layer in layers) { var period = 2 * (layer.Range - 1); var caught = (layer.ID + delay) % period == 0; if (caught) { hasBeenCaught = true; break; } } if (!hasBeenCaught) { successfulTrip = true; break; } else { delay++; } } return(delay); }
public string Solve() { long composite = 600851475143; DateTime start = DateTime.Now; HashSet <long> knownPrimeFactors = FindLowerPrimes(composite); DateTime end = DateTime.Now; Console.WriteLine("Found lower primes in {0} seconds", (end - start).TotalSeconds); start = DateTime.Now; knownPrimeFactors = FindHigherPrimes(knownPrimeFactors, composite); end = DateTime.Now; Console.WriteLine("Found higher primes in {0} seconds", (end - start).TotalSeconds); return(knownPrimeFactors.Max().ToString()); }
public static long Part2() { const string path = Helpers.inputPath + @"\day05\input.txt"; IList <(int, int)> inputs = ProcessInputFile(path); ISet <long> ids = new HashSet <long>(inputs.Select(inp => (long)(inp.Item1 * 8 + inp.Item2))); long minId = ids.Min(); long maxId = ids.Max(); for (long i = minId + 1; i < maxId; i++) { if (!ids.Contains(i) && ids.Contains(i - 1) && ids.Contains(i + 1)) { return(i); } } return(-1); }
// Largest product in a grid // Problem 11 // In the 20×20 grid below, four numbers along a diagonal line have been marked in red. /* 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 * 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 * 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 * 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 * 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 * 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 * 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 * 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 * 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 * 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 * 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 * 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 * 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 * 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 * 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 * 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 * 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 * 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 * 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 * 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 */ // The product of these numbers is 26 × 63 × 78 × 14 = 1788696. // What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid? static void Main(string[] args) { var grid = new Grid(20, 20, // This is the size of the grid <- 08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08, 49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00, 81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65, 52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 36, 91, 22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80, 24, 47, 32, 60, 99, 03, 45, 02, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50, 32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70, 67, 26, 20, 68, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21, 24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72, 21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95, 78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92, 16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57, 86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58, 19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40, 04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66, 88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69, 04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36, 20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16, 20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54, 01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48); var greatestProducts = new HashSet <int>(); // Okay let's loop through all numbers in the grid and find the one with the greatest product foreach (Cell <int> cell in grid) { int[] sums = new int[8]; for (int i = 0; i < 8; i++) { var neighbours = grid.GetNeighbours(cell, (Direction)i, 4); if (neighbours.Count > 0) { sums[i] = neighbours.Aggregate((a, b) => a * b); } } greatestProducts.Add(sums.Max()); } Console.WriteLine(greatestProducts.Max()); Console.ReadKey(); }
public void Part1() { var replacements = new Dictionary <string, List <string> >(); var replacementLengths = new HashSet <int>(); string toReplace = null; parse(inputString, out replacements, out replacementLengths, out toReplace); //Console.WriteLine("replacements:"); //foreach (var kv in replacements) //{ // Console.WriteLine($" {kv.Key}: {String.Join(", ", kv.Value)}"); //} int maxLength = replacementLengths.Max(); var latest = new ForgetfullList(maxLength); var result = new HashSet <string>(); for (int i = 0; i < toReplace.Length; i++) { latest.Add(toReplace[i]); var latestString = latest.ToString(); //Console.WriteLine($"latestString={latestString}"); for (int len = 1; len <= latestString.Length; len++) { var current = latestString.Substring(latestString.Length - len, len); //Console.WriteLine($"current={current}"); if (replacements.ContainsKey(current)) { foreach (var replacement in replacements[current]) { string prefix = toReplace.Remove(i - len + 1); var postfix = ""; if (i + 1 < toReplace.Length) { postfix = toReplace.Substring(i + 1); } //Console.WriteLine($"Add: {prefix}_{replacement}_{postfix}"); result.Add(prefix + replacement + postfix); } } } } Assert.AreEqual(576, result.Count); }
public static IEnumerable <int> SweepLine(IEnumerable <Building> buildings) { ReadOnlyCollection <Building> buildingsList = buildings.OrderBy(x => x.Left).ToReadOnlyCollection(); Dictionary <int, List <Event> > events = new Dictionary <int, List <Event> >(); foreach (var building in buildingsList) { events.GetOrAddValue(building.Left).Add(new Event { Building = building, Mode = EventMode.Add }); events.GetOrAddValue(building.Right).Add(new Event { Building = building, Mode = EventMode.Remove }); } HashSet <Building> currentHeights = new HashSet <Building>(); int lastHeight = 0; foreach (var position in events.OrderBy(x => x.Key)) { foreach (var buildingEvent in position.Value) { if (buildingEvent.Mode == EventMode.Add) { Assert.IsTrue(currentHeights.Add(buildingEvent.Building)); } if (buildingEvent.Mode == EventMode.Remove) { Assert.IsTrue(currentHeights.Remove(buildingEvent.Building)); } } int max = currentHeights.Any() ? currentHeights.Max(x => x.Height) : 0; if (lastHeight == max) { continue; } yield return(position.Key); yield return(max); lastHeight = max; } }
private string GetGridResult(HashSet <Point> points, bool getText = false) { //Check if points are on 1 line var YDifference = points.Max(c => c.PositionY) - points.Min(c => c.PositionY); if (YDifference < (Test ? 8 : 11)) { if (!getText) { return("DONE"); } var strideX = Test ? 30 : 100; var strideY = Test ? 10 : 10; var grid = new byte[strideX * strideY]; var upperLeftY = points.Min(c => c.PositionY); var upperLeftX = points.Min(c => c.PositionX); //Fill grid with values foreach (var item in points) { grid[Math.Abs(item.PositionX) - upperLeftX + ((Math.Abs(item.PositionY) - upperLeftY) * strideX)] = 1; } var sb = new StringBuilder(); sb.AppendLine(); for (int y = 0; y < strideY; y++) { for (int x = 0; x < strideX; x++) { var position = x + (y * strideX); sb.Append((grid[position] == 1) ? "#" : "."); } sb.AppendLine(); } if (Test) { Debug.WriteLine(sb.ToString()); } return(sb.ToString()); } return(null); }
public InventoryCache(IServer engine, IInventoryLoader loader, IInventorySaver saver) { _inventories = new Dictionary <long, Inventory>(); _engine = engine; _subscriptions = new Dictionary <long, HashSet <RemotePlayer> >(); _loader = loader ?? new NullLoader(); _saver = saver ?? new NullSaver(); _availableIds = _loader.GetAvailableIds(); if (_availableIds.Count > 0) { _nextInventoryId = _availableIds.Max() + 1; } _engine.RegisterMessageCallback(typeof(ClientRequestInventoryUpdates), HandlePerformSubscription); _engine.RegisterMessageCallback(typeof(ClientCancelInventoryUpdates), HandleCancelSubscription); }
void Solve() { var X = F; var ps = new HashSet <int> { 1 }; for (var n = 2; n <= 40; n++) { var a = n * n; while (a <= X) { ps.Add(a); a *= n; } } WriteLine(ps.Max()); }
public void CalculteParseAddresses() { if (addresses.Count == 0) { return; } ushort count = (ushort)((addresses.Max() - addresses.Min()) + 1); ushort poolCount = (ushort)(((count - 1) / ParseSize) + 1); ReadMap[] maps = new ReadMap[poolCount]; for (int i = 0; i < poolCount; i++) { maps[i].StartAddress = (ushort)(addresses.Min() + (i * ParseSize)); maps[i].Range = ParseSize; } maps[poolCount - 1].Range = (ushort)(count - ((poolCount - 1) * ParseSize)); Maps = maps; }
public long Solve() { var sum = 0; for (var number = 3; number <= 1000; number++) { var divisor = number * number; var remainders = new HashSet<int> { 2 }; for (var n = 1; n <= 2 * number; n = n + 2) { remainders.Add((2 * n * number) % divisor); } sum += remainders.Max(); } return sum; }
private void addEntryToolStripMenuItem_Click(object sender, EventArgs e) { if (_enumType != null) { long value = 0; HashSet <long> values = new HashSet <long>(); string name = GenerateName(); if (name != null) { foreach (EnumParserTypeEntry ent in _enumType.Entries) { if (!values.Contains(ent.Value)) { values.Add(ent.Value); } } if (!_enumType.IsFlags) { if (values.Count > 0) { value = values.Max() + 1; } } else { // Find the next positive enum value for simplicity for (value = 1; value < 0x4000000000000001L; value <<= 1) { if (!values.Contains(value)) { break; } } } EnumParserTypeEntry entry = new EnumParserTypeEntry(name, value); _enumType.AddEntry(entry); AddEnumEntryToList(entry, true); } } }
static MqttQualityOfServiceLevel GetEffectiveQoS(MqttQualityOfServiceLevel qosLevel, HashSet <MqttQualityOfServiceLevel> subscribedQoSLevels) { MqttQualityOfServiceLevel effectiveQoS; if (subscribedQoSLevels.Contains(qosLevel)) { effectiveQoS = qosLevel; } else if (subscribedQoSLevels.Count == 1) { effectiveQoS = subscribedQoSLevels.First(); } else { effectiveQoS = subscribedQoSLevels.Max(); } return(effectiveQoS); }
private bool IsPandigital(long number) { var lenght = (int)Math.Log10(number) + 1; var digits = new HashSet<long>(); while (number > 0) { var digit = number % 10; if (digit == 0) return false; digits.Add(digit); number = number / 10; } return (digits.Count() == lenght) && digits.Max() == lenght; }
/* TREES ////////////////////////////////////////////////////////////////////////////////////////////////// * * -number of nodes on each level 2x as we move down the tree (for a perfect / full BINARY SEARCH tree) * -number of nodes on the LAST level equals the sum of all the nodes on the other levels + 1 (for perfect tree) * -depth of tree is # of levels (root is level 0). COUNT the number of EDGES to leaf. * -height starts at leaf. = 1+ max(height(L), height(R)) * -BST: left is smaller than node, right is larger than node * -O(log n) lookup for BST * * GRAPHS ////////////////////////////////////////////////////////////////////////////////////////////////// * * -nodes / vertex are connected by EDGES * -useful for cases where things connect to other things * -most graph algorithms are O(n log n) or slower * -nodes are stored in an array (as a dictionary), usually as adjency lists (dictionary of node, and a linked list of connections) * * Breadth-First Search: explore level by level starting at root. used to find shortest path and any other reachable node. requires more memory than DFS. Uses a queue (hit all 1-hops, then all 2-hops, and so on). Memory used is proportional to breadth of tree. O(N+M), where M = current node's neighbors (ie connections between the users). * * Depth-First Search: go as deep as possible down 1 path before trying another. uses recursion. Uses a stack. Memory used is proportional to depth of tree. * * * -is there a path btw 2 nodes? run either search from one node and see if you reach the other. * -shortest path? BFS from 1 node and backtrack once you reach the second. * * SIMPLIFY THE PROBLEM: solve for easier problem (eg. just check one hop away) and then adapt to solve for final problem. * */////////////////////////////////////////////////////////////////////////////////////////////////// public static bool IsBalanced(BinaryTreeNode treeRoot) //my function doesnt short circuit. not ideal... { var heightHash = new HashSet <int>(); GetDepth(treeRoot, 0, heightHash); if (heightHash.Count > 2) { return(false); } else if (heightHash.Max() - heightHash.Min() > 1) { return(false); } else { return(true); } }
public static int MaxScore(string s) { List <int> score = s.Select(x => int.Parse(x.ToString())).ToList(); int leftScore = 0; int rightScore = 0; HashSet <int> scoreList = new HashSet <int>(); for (int i = 1; i < score.Count; i++) { leftScore = score.Take(i).ToList().Count(x => x == 0); rightScore = score.Skip(i).ToList().Count(x => x == 1); scoreList.Add(leftScore + rightScore); } return(scoreList.Max()); }
private int getSegmentEndTime(HashSet <int> fragmentationTimes, List <IFragmentableCommand> commands) { var startTime = fragmentationTimes.Min(); int endTime; var maxCommandCount = osbSprite.CommandSplitThreshold; //split the last 2 segments evenly so we don't have weird 5 command leftovers if (commands.Count < osbSprite.CommandSplitThreshold * 2 && commands.Count > osbSprite.CommandSplitThreshold) { maxCommandCount = (int)Math.Ceiling(commands.Count / 2.0); } if (commands.Count < maxCommandCount) { endTime = fragmentationTimes.Max() + 1; } else { var lastCommand = commands.OrderBy(c => c.StartTime).ElementAt(maxCommandCount - 1); if (fragmentationTimes.Contains((int)lastCommand.StartTime) && lastCommand.StartTime > startTime) { endTime = (int)lastCommand.StartTime; } else { if (fragmentationTimes.Any(t => t < (int)lastCommand.StartTime)) { endTime = fragmentationTimes.Where(t => t < (int)lastCommand.StartTime).Max(); if (endTime == startTime) // segment can't be <= MaxCommandCount, so we use the smallest available { endTime = fragmentationTimes.First(t => t > startTime); } } else { endTime = fragmentationTimes.First(t => t > startTime); } } } return(endTime); }
public void LayoutTools(string category) { needScroll = false; currentScrollPosition = 0; scrollPositions.Clear(); scrollPositions.Add(0); currentTab.Clear(); tabHeight = categories.Max(s => (int)textMetrics.MeasureString(s, textFont).Height) + tabPadding * 2; tabWidth = categories.Sum(s => (int)textMetrics.MeasureString(s, textFont).Width) + (tabPadding * 2 + tabSpacing) * categories.Count; int maxRowHeight = 0; const int initialX = 5 + scrollArrowWidth; int x = initialX; int y = y = 5 + tabHeight + 5; int toolAreaWidth = initialSize.Width - scrollArrowWidth * 2; int i = 0; foreach (ToolSpec spec in tools) { if (!spec.category.Contains(category)) { continue; } Size toolSize = spec.bmp.Size; currentTab.Add(spec); if (x + toolSize.Width >= toolAreaWidth) { x = initialX; //y += maxRowHeight; needScroll = true; scrollPositions.Add(i); } spec.rectangle = new Rectangle(x, y, toolSize.Width, toolSize.Height); x += toolSize.Width + toolSpacing; maxRowHeight = Math.Max(maxRowHeight, toolSize.Height); i++; } bitmap = new Bitmap(initialSize.Width, y + maxRowHeight + 10 + tabHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); UpdateBitmap(category, tabWidth, tabHeight); }
internal List <ChangesetData> GetChangesets(HashSet <int> changeSets) { List <ChangesetData> result = new List <ChangesetData>(changeSets.Count); HashSet <int> changeSetsCopy = new HashSet <int>(changeSets); foreach (var item in changeSets) { ChangesetData found; if (changesetCache.TryGetValue(item, out found)) { result.Add(found); changeSetsCopy.Remove(item); } } if (changeSetsCopy.Count == 0) { return(result); } var min = new ChangesetVersionSpec(changeSetsCopy.Min()); var max = new ChangesetVersionSpec(changeSetsCopy.Max()); var changes = VersionControlServer.QueryHistory(ProjectPath, VersionSpec.Latest, 0, RecursionType.Full, null, min, max, Int32.MaxValue, false, false); foreach (Changeset item in changes) { ChangesetData found; if (!changesetCache.TryGetValue(item.ChangesetId, out found)) { found = new ChangesetData(item.Comment, null); changesetCache[item.ChangesetId] = found; } if (changeSetsCopy.Contains(item.ChangesetId)) { result.Add(found); } } return(result); }
public void Execute() { Console.WriteLine("\nStep 2: Enkele eenvoudige Linq operatoren.\n"); // Enkele Linq methodes op collecties van getallen int[] getallen = { 2, 8, 10 }; Console.WriteLine($"De som is {getallen.Sum()}"); List <int> myList = new List <int>(); myList.Add(2); myList.Add(10); myList.Add(10); Console.WriteLine($"De som is van de getallen in de lijst is {myList.Sum()}"); HashSet <double> getallenSet = new HashSet <double> { 2.5, 8.4, 10.6 }; getallenSet.Add(2.5); getallenSet.Add(8.4); getallenSet.Add(10.6); Console.WriteLine($"De som van de getallen in de hashset is {getallenSet.Sum()} ..."); // vervang "{0}" door een correcte Linq expressie Console.WriteLine($"Het minimum in de hashset is {0} ..."); Console.WriteLine($"Het minimum in de hashset is {getallenSet.Min()} ..."); Console.WriteLine($"De maximum in de hashset is {getallenSet.Max()} ..."); Stack <float> getallenStack = new Stack <float>(); getallenStack.Push(1.5F); getallenStack.Push(2.6F); getallenStack.Push(5F); //float somStack = getallenStack.Sum(); Console.WriteLine($"De som van de getallen op de stack is {getallenStack.Sum()} ..."); // vervang "{0}" door een correcte Linq expressie Console.WriteLine($"Het gemiddelde van de getallen op de stack is {getallenStack.Average()} ..."); Console.WriteLine($"Het aantal getallen op de stack is {getallenStack.Count()} ..."); Console.WriteLine("Druk op enter om verder te gaan..."); Console.ReadLine(); }
public string Solve() { HashSet <int> palindromes = new HashSet <int>(); for (int leader = 999; leader > 100; leader--) { for (int follower = 999; follower >= 100; follower--) { int next = leader * follower; if (IsPalindrome(next)) { palindromes.Add(next); } } } return(palindromes.Count > 0 ? palindromes.Max().ToString() : "No palindrome found."); }
static void Day5() { var seats = File.ReadAllLines("input_5.txt"); var ids = new HashSet <int>(); foreach (var seat in seats) { var row = BinSearch(seat.Substring(0, 7), 0, 127); var col = BinSearch(seat.Substring(7), 0, 7); ids.Add(row * 8 + col); } for (int i = 0; i < ids.Max(); i++) { if (!ids.Contains(i)) { Console.WriteLine(i); } } }
public long FindMinimumLatency(string[] lines) { var graph = new Graph(); graph.Parse(lines.Skip(2).ToArray()); var clientVerticesLabels = lines[1].Split(' '); var clientVertices = new HashSet<Vertex>(clientVerticesLabels.Select(vertexLabel => graph[vertexLabel])); long minimumLatency = long.MaxValue; foreach (var currentVertex in graph.Vertices.Where(vertex => !clientVertices.Contains(vertex))) { var roadmap = graph.Dijkstra(currentVertex); var currentMinimumLatency = clientVertices.Max(x => roadmap[x].Distance); if (currentMinimumLatency < minimumLatency) { minimumLatency = currentMinimumLatency; } } return minimumLatency; }
internal int ComputeLargestManhattan() { HashSet <int> manhattans = new HashSet <int>(); List <Point3> offsets = new List <Point3>(); GetOffsetsOfNearbyScanners(offsets, Point3.Zero); foreach (Point3 left in offsets) { foreach (Point3 right in offsets) { if (left != right) { manhattans.Add((left - right).Manhattan()); } } } return(manhattans.Max()); }
/// <summary> /// Checks for collision between 2 entities /// </summary> /// <param name="entity"> /// The entity. /// </param> /// <param name="other"> /// The other entity. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> public static bool CheckSingleCollision(IEntity entity, IEntity other) { ICollection <BoundingSphere> boundingSpheres = new HashSet <BoundingSphere>(); foreach (var mesh in entity.Model.Meshes) { boundingSpheres.Add(mesh.BoundingSphere.Transform(entity.TransformationMatrix)); } float minCollisionRange = boundingSpheres.Max(bs => bs.Radius) * 2; return(Vector3.Distance(entity.Position, other.Position) < minCollisionRange && other.Model.Meshes .Any(mesh => boundingSpheres .Any(bs => mesh.BoundingSphere .Transform(other.TransformationMatrix) .Intersects(bs)))); }
public ExtrusionColors(HashSet <float> speeds) { if (speeds.Any()) { min = speeds.Min(); max = speeds.Max(); } else { min = 0; max = 1; } range = max - min; delta = startColor - endColor; foreach (var speed in speeds) { speedColors[speed] = this.ComputeColor(speed); } }
/// <summary> /// Set the given msg ready status if no other status are actually running. /// </summary> public void ReleaseStatus(uint id, string msg = "Ready.") { var empty = false; var idMsg = ""; string back_msg = null; lock (statusIdLck) { statusIdSet.Remove(id); empty = statusIdSet.Count == 0; if (!empty) { back_msg = statusIdMsgDict[statusIdSet.Max()]; } #if DEBUG if (!statusIdMsgDict.ContainsKey(id)) { Debugger.Break(); } idMsg = statusIdMsgDict[id]; statusIdMsgDict.Remove(id); // avoid app crash if any #endif } if (empty) { Status = msg; } else { if (back_msg != null) { Status = back_msg; } else { Status = $"{idMsg} [done]"; } } }
static void Main() { int n = C.NextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = C.NextInt(); } HashSet <int> hs = new HashSet <int>(); foreach (var i in a) { hs.Add(i); } if (hs.Count > 2) { C.WriteLine("No"); } if (hs.Count == 2) { int M, m; M = hs.Max(); m = hs.Min(); if (M - m != 1) { C.WriteLine("No"); Environment.Exit(0); } int x = a.Count(s => s == m); int y = n - x; bool f = x < M && 2 * (M - x) <= y; C.WriteLine(f ? "Yes" : "No"); } if (hs.Count == 1) { int k = a[0]; bool f = k == n - 1 || 2 * k <= n; C.WriteLine(f ? "Yes" : "No"); } }
public int[] MaxSlidingWindow(int[] nums, int k) { var numCount = new Dictionary <int, int>(); var numSet = new HashSet <int>(); var retVal = new List <int>(); for (int i = 0, kOriginal = k; i < nums.Length; ++i) { insert(numCount, numSet, nums[i]); --k; if (k < 0) { delete(numCount, numSet, nums[i - kOriginal]); } if (k <= 0) { retVal.Add(numSet.Max()); } } return(retVal.ToArray()); }
public ISet <UInt64> GetSetOfSquaresFromFile() { Console.Out.WriteLine("Reading Square Numbers from file..."); var s = Stopwatch.StartNew(); var squares = File.ReadAllLines(Constants.RESOURCE_LOCATION + "squares.txt") .Select(line => line.Split(',').Select(UInt64.Parse).ToArray()).ToList(); var squaresSet = new HashSet <UInt64>(); foreach (var i in squares.SelectMany(primeArray => primeArray)) { squaresSet.Add(i); } s.Stop(); Console.Out.WriteLine("Reading {0} square numbers took {1}, max square is: {2}\r\n", squaresSet.Count, s.Elapsed, squaresSet.Max()); return(squaresSet); }
public void Migrate(IDocumentStore store, Assembly assemblyContainingMigrations, long toVersion = -1) { var migrationTypes = GetMigrationTypes(assemblyContainingMigrations); var toMax = toVersion < 0; if (!toMax) EnsureCanMigrate(toVersion, migrationTypes, assemblyContainingMigrations); if (migrationTypes.Count == 0) return; if (toMax) toVersion = long.MaxValue; using (var session = new IndexSavingDocumentSession(store.OpenSession())) { var txId = Guid.NewGuid(); session.Advanced.DatabaseCommands.PromoteTransaction(txId); try { var appliedMigrations = GetAppliedMigrations(store); var appliedVersions = new HashSet<long>(appliedMigrations.Select(m => m.Version)); var currentMaxVersion = appliedVersions.Count == 0 ? 0 : appliedVersions.Max(); if (toVersion > currentMaxVersion) { MigrateUpTo(toVersion, appliedVersions, migrationTypes, session); } else { MigrateDownTo(toVersion, appliedMigrations, appliedVersions, migrationTypes, session); } session.SaveChanges(); session.Advanced.DatabaseCommands.Commit(txId); } catch { session.RestoreIndexes(); session.Advanced.DatabaseCommands.Rollback(txId); throw; } } }
public long Solve() { var primeUtil = new Prime(Limit); var numbers = new HashSet<long>(); foreach (var prime in primeUtil.PrimeList) { if (prime < Limit) numbers.Add(prime + 1); } Console.WriteLine(numbers.Count); Console.WriteLine(numbers.Max()); var factorization = new Dictionary<long, Dictionary<long, long>>(); foreach (var number in numbers) { factorization.Add(number, primeUtil.GetDecomposition(number)); } Console.WriteLine("Faktorizace Done"); return 0; }
public void HashSetExtensions_Max_ThrowsExceptionIfHashSetIsEmpty() { var set = new HashSet<Int32>(); Assert.That(() => set.Max(), Throws.TypeOf<InvalidOperationException>()); }
private List<Literal> generarCandidatos(HashSet<Literal> predicados, HashSet<string> usados) { List<Literal> candidatos = new List<Literal>(); foreach(var predicado in predicados) { int natt_nuevo = Convert.ToInt32(usados.Max()); HashSet<string> usados_cpy = new HashSet<string>(usados); for (int i = 0; i < predicado.nAtt-1; i++) { usados_cpy.Add("" + (i+natt_nuevo+1) ); } // añadir natt_nuevo a usados foreach (var atributos in usados_cpy.Repetitions(predicado.nAtt)) { candidatos.Add(new Literal(predicado.Nombre, predicado.nAtt, atributos)); } } return candidatos; }
public void HashSetExtensions_Max_ThrowsExceptionIfHashSetIsEmpty() { var set = new HashSet<Int32>(); set.Max(); }
//===================================================================== /// <summary> /// Validate the documentation source information and copy the files to the working folder /// </summary> /// <exception cref="BuilderException">This is thrown if any of the information is invalid</exception> private void ValidateDocumentationSources() { List<string> commentsList = new List<string>(); Dictionary<string, MSBuildProject> projectDictionary = new Dictionary<string, MSBuildProject>(); HashSet<string> targetFrameworksSeen = new HashSet<string>(), targetFrameworkVersionsSeen = new HashSet<string>(); MSBuildProject projRef; XPathDocument testComments; XPathNavigator navComments; int fileCount; string workingPath, lastSolution = null; this.ReportProgress(BuildStep.ValidatingDocumentationSources, "Validating and copying documentation source information"); assembliesList = new Collection<string>(); referenceDictionary = new Dictionary<string, Tuple<string, string, List<KeyValuePair<string, string>>>>(); commentsFiles = new XmlCommentsFileCollection(); if(this.ExecutePlugIns(ExecutionBehaviors.InsteadOf)) return; // It's possible a plug-in might want to add or remove assemblies so we'll run them before checking // to see if the project has any. this.ExecutePlugIns(ExecutionBehaviors.Before); if(project.DocumentationSources.Count() == 0) throw new BuilderException("BE0039", "The project does not have any documentation sources defined"); // Clone the project's references. These will be added to a build project later on so we'll note the // necessary information needed to create the reference in the future project. foreach(string refType in (new string[] { "Reference", "COMReference" })) foreach(ProjectItem reference in project.MSBuildProject.GetItems(refType)) referenceDictionary.Add(reference.EvaluatedInclude, Tuple.Create(reference.ItemType, reference.EvaluatedInclude, reference.Metadata.Select(m => new KeyValuePair<string, string>(m.Name, m.EvaluatedValue)).ToList())); // Convert project references to regular references that point to the output assembly. Project // references get built and we may not have enough info for that to happen successfully. As such, // we'll assume the project has already been built and that its target exists. foreach(ProjectItem reference in project.MSBuildProject.GetItems("ProjectReference")) { // Ignore references used only for MSBuild dependency determination var refOutput = reference.GetMetadata(BuildItemMetadata.ReferenceOutputAssembly); if(refOutput != null && refOutput.EvaluatedValue.Equals("false", StringComparison.OrdinalIgnoreCase)) { this.ReportProgress("Ignoring reference to '{0}' which is only used for MSBuild dependency " + "determination", reference.EvaluatedInclude); continue; } using(projRef = new MSBuildProject(reference.EvaluatedInclude)) { // .NET 4.5 supports a property that tells MSBuild to put the project output into a // project-specific folder in OutDir. var projectSpecificFolder = project.MSBuildProject.AllEvaluatedProperties.FirstOrDefault( p => p.Name == "GenerateProjectSpecificOutputFolder"); bool usesProjectSpecificOutput = (projectSpecificFolder != null && !String.IsNullOrWhiteSpace(projectSpecificFolder.EvaluatedValue) && Convert.ToBoolean(projectSpecificFolder.EvaluatedValue, CultureInfo.InvariantCulture)); projRef.SetConfiguration(project.Configuration, project.Platform, project.MSBuildOutDir, usesProjectSpecificOutput); referenceDictionary.Add(projRef.AssemblyName, Tuple.Create("Reference", Path.GetFileNameWithoutExtension(projRef.AssemblyName), (new [] { new KeyValuePair<string, string>("HintPath", projRef.AssemblyName) }).ToList())); } } try { // For each source, make three passes: one for projects, one for assemblies and one for comments // files. Projects and comments files are optional but when all done, at least one assembly must // have been found. foreach(DocumentationSource ds in project.DocumentationSources) { fileCount = 0; this.ReportProgress("Source: {0}", ds.SourceFile); foreach(var sourceProject in ds.Projects( !String.IsNullOrEmpty(ds.Configuration) ? ds.Configuration : project.Configuration, !String.IsNullOrEmpty(ds.Platform) ? ds.Platform : project.Platform)) { // NOTE: This code in EntityReferenceWindow.IndexComments should be similar to this! // Solutions are followed by the projects that they contain if(sourceProject.ProjectFileName.EndsWith(".sln", StringComparison.OrdinalIgnoreCase)) { lastSolution = sourceProject.ProjectFileName; continue; } if(!projectDictionary.ContainsKey(sourceProject.ProjectFileName)) { // These are handled below this.ReportProgress(" Found project '{0}'", sourceProject.ProjectFileName); // .NET 4.5 supports a property that tells MSBuild to put the project output into a // project-specific folder in OutDir. var projectSpecificFolder = project.MSBuildProject.AllEvaluatedProperties.FirstOrDefault( p => p.Name == "GenerateProjectSpecificOutputFolder"); bool usesProjectSpecificOutput = (projectSpecificFolder != null && !String.IsNullOrWhiteSpace(projectSpecificFolder.EvaluatedValue) && Convert.ToBoolean(projectSpecificFolder.EvaluatedValue, CultureInfo.InvariantCulture)); projRef = new MSBuildProject(sourceProject.ProjectFileName); // Use the project file configuration and platform properties if they are set. If not, // use the documentation source values. If they are not set, use the SHFB project settings. projRef.SetConfiguration( !String.IsNullOrEmpty(sourceProject.Configuration) ? sourceProject.Configuration : !String.IsNullOrEmpty(ds.Configuration) ? ds.Configuration : project.Configuration, !String.IsNullOrEmpty(sourceProject.Platform) ? sourceProject.Platform : !String.IsNullOrEmpty(ds.Platform) ? ds.Platform : project.Platform, project.MSBuildOutDir, usesProjectSpecificOutput); // Add Visual Studio solution macros if necessary if(lastSolution != null) projRef.SetSolutionMacros(lastSolution); projectDictionary.Add(sourceProject.ProjectFileName, projRef); } else this.ReportProgress(" Ignoring duplicate project file '{0}'", sourceProject.ProjectFileName); fileCount++; } foreach(string asmName in ds.Assemblies) { if(!assembliesList.Contains(asmName)) { // Assemblies are parsed in place by MRefBuilder so we don't have to do anything with // them here. this.ReportProgress(" Found assembly '{0}'", asmName); assembliesList.Add(asmName); } else this.ReportProgress(" Ignoring duplicate assembly file '{0}'", asmName); fileCount++; } foreach(string commentsName in ds.CommentsFiles) { if(!commentsList.Contains(commentsName)) { // These are handled below commentsList.Add(commentsName); } else this.ReportProgress(" Ignoring duplicate comments file '{0}'", commentsName); fileCount++; } if(fileCount == 0) this.ReportWarning("BE0006", "Unable to locate any documentation sources for '{0}' " + "(Configuration: {1} Platform: {2})", ds.SourceFile, !String.IsNullOrEmpty(ds.Configuration) ? ds.Configuration : project.Configuration, !String.IsNullOrEmpty(ds.Platform) ? ds.Platform : project.Platform); } // Parse projects for assembly, comments, and reference info if(projectDictionary.Count != 0) { this.ReportProgress("\r\nParsing project files"); foreach(MSBuildProject msbProject in projectDictionary.Values) { workingPath = msbProject.AssemblyName; if(!String.IsNullOrEmpty(workingPath)) { if(!File.Exists(workingPath)) throw new BuilderException("BE0040", "Project assembly does not exist: " + workingPath); if(!assembliesList.Contains(workingPath)) { // Assemblies are parsed in place by MRefBuilder so we don't have to do anything // with them here. this.ReportProgress(" Found assembly '{0}'", workingPath); assembliesList.Add(workingPath); } else this.ReportProgress(" Ignoring duplicate assembly file '{0}'", workingPath); } else throw new BuilderException("BE0067", String.Format(CultureInfo.CurrentCulture, "Unable to obtain assembly name from project file '{0}' using Configuration " + "'{1}', Platform '{2}'", msbProject.ProjectFile.FullPath, msbProject.ProjectFile.AllEvaluatedProperties.Last( p => p.Name == BuildItemMetadata.Configuration).EvaluatedValue, msbProject.ProjectFile.AllEvaluatedProperties.Last( p => p.Name == BuildItemMetadata.Platform).EvaluatedValue)); workingPath = msbProject.XmlCommentsFile; if(!String.IsNullOrEmpty(workingPath)) { if(!File.Exists(workingPath)) throw new BuilderException("BE0041", "Project XML comments file does not exist: " + workingPath); if(!commentsList.Contains(workingPath)) { // These are handled below commentsList.Add(workingPath); } else this.ReportProgress(" Ignoring duplicate comments file '{0}'", workingPath); } // Note the platforms seen and the highest framework version used targetFrameworksSeen.Add(msbProject.TargetFrameworkIdentifier); targetFrameworkVersionsSeen.Add(msbProject.TargetFrameworkVersion); // Clone the project's reference information msbProject.CloneReferenceInfo(referenceDictionary); } // If we saw multiple framework types in the projects, stop now. Due to the different // assemblies used, we cannot mix the project types within the same SHFB project. They will // need to be documented separately and can be merged using the Version Builder plug-in if // needed. if(targetFrameworksSeen.Count > 1) throw new BuilderException("BE0070", "Differing framework types were detected in the " + "documentation sources (i.e. .NET, Silverlight, Portable). Due to the different " + "sets of assemblies used, the different frameworks cannot be mixed within the same " + "documentation project. See the error number topic in the help file for details."); // If a project with a higher framework version was found, switch to that version now var projectFramework = reflectionDataDictionary.CoreFrameworkMatching( targetFrameworksSeen.First(), new Version(targetFrameworkVersionsSeen.Max(f => f)), true); if(frameworkReflectionData != projectFramework) { // If redirected and no suitable version was found, we can't go any further if(projectFramework == null) throw new BuilderException("BE0073", String.Format(CultureInfo.CurrentCulture, "A project with a different or higher framework version was found but that " + "version ({0} {1}) or a suitable redirected version was not found on this " + "system. The build cannot continue.", targetFrameworksSeen.First(), targetFrameworkVersionsSeen.Max(f => f))); this.ReportWarning("BE0007", "A project with a different or higher framework version " + "was found. Changing project FrameworkVersion property from '{0}' to '{1}' for " + "the build.", project.FrameworkVersion, projectFramework.Title); project.FrameworkVersion = projectFramework.Title; frameworkReflectionData = projectFramework; } } } finally { // Dispose of any MSBuild projects that we loaded foreach(var p in projectDictionary.Values) p.Dispose(); } if(assembliesList.Count == 0) throw new BuilderException("BE0042", "You must specify at least one documentation source in " + "the form of an assembly or a Visual Studio solution/project file"); // Log the references found, if any if(referenceDictionary.Count != 0) { this.ReportProgress("\r\nReferences to include (excluding framework assemblies):"); string[] keys = new string[referenceDictionary.Keys.Count]; referenceDictionary.Keys.CopyTo(keys, 0); Array.Sort(keys); // Filter out references related to the framework. MRefBuilder will resolve these // automatically. foreach(string key in keys) if(frameworkReflectionData.ContainsAssembly(key)) referenceDictionary.Remove(key); else this.ReportProgress(" {0}", key); if(referenceDictionary.Count == 0) this.ReportProgress(" None"); } if(commentsList.Count != 0) this.ReportProgress("\r\nCopying XML comments files"); // XML comments files are copied to the working folder in case they need to be fixed up foreach(string commentsName in commentsList) { workingPath = workingFolder + Path.GetFileName(commentsName); // Warn if there is a duplicate and copy the comments file to a unique name to preserve its // content. if(File.Exists(workingPath)) { workingPath = workingFolder + Guid.NewGuid().ToString("B"); this.ReportWarning("BE0063", "'{0}' matches a previously copied comments filename. The " + "duplicate will be copied to a unique name to preserve the comments it contains.", commentsName); } try { // Not all XML files found may be comments files. Ignore those that are not. testComments = new XPathDocument(commentsName); navComments = testComments.CreateNavigator(); if(navComments.SelectSingleNode("doc/members") == null) { this.ReportWarning("BE0005", "File '{0}' does not contain a 'doc/members' node and " + "will not be used as an XML comments file.", commentsName); continue; } } catch(Exception ex) { this.ReportWarning("BE0061", "File '{0}' could not be loaded and will not be used as an " + "XML comments file. Error: {1}", commentsName, ex.Message); continue; } File.Copy(commentsName, workingPath, true); File.SetAttributes(workingPath, FileAttributes.Normal); // Add the file to the XML comments file collection commentsFiles.Add(new XmlCommentsFile(workingPath)); this.ReportProgress(" {0} -> {1}", commentsName, workingPath); } if(commentsFiles.Count == 0) this.ReportWarning("BE0062", "No XML comments files found. The help file will not contain " + "any member comments."); this.ExecutePlugIns(ExecutionBehaviors.After); }
/// <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(); }
/// <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; }
public void HashSetExtensions_Max_ReturnsMaxValue() { var set = new HashSet<Int32>() { 4, 5, 6, 99, 10, 1, 12, 45 }; var result = set.Max(); TheResultingValue(result).ShouldBe(99); }
/// <summary> /// Sugiyama step 1: Cycle Removal /// This method implements an enhanced Greedy Cycle Removal heuristic /// proposed by Eades et al, 1993. /// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.7745 /// </summary> public void RemoveCycles() { HashSet<Node> RemainingNodes = new HashSet<Node>(Nodes); HashSet<Edge> AcyclicEdges = new HashSet<Edge>(); while (RemainingNodes.Count > 0) { // Remove all sink nodes HashSet<Node> selected = new HashSet<Node>(RemainingNodes.Where( n => n.RightEdges.Count(x => x.Active) == 0)); foreach (Node n in selected) { foreach (Edge e in n.LeftEdges.Where(x => x.Active)) { AcyclicEdges.Add(e); e.Active = false; } } // Remove all isolated nodes RemainingNodes.ExceptWith(selected); // Remove all source nodes selected = new HashSet<Node>(RemainingNodes.Where( n => n.LeftEdges.Count(x => x.Active) == 0)); foreach (Node n in selected) { foreach (Edge e in n.RightEdges.Where(x => x.Active)) { AcyclicEdges.Add(e); e.Active = false; } } // Remove all isolated nodes RemainingNodes.ExceptWith(selected); // Remove one node with the largest number of outgoing edges if (RemainingNodes.Count > 0) { int max = RemainingNodes.Max(x => x.RightEdges.Count(y => y.Active) - x.LeftEdges.Count(y => y.Active)); Node n = RemainingNodes.First(x => x.RightEdges.Count(y => y.Active) - x.LeftEdges.Count(y => y.Active) == max); AcyclicEdges.UnionWith(n.RightEdges.Where(x => x.Active)); foreach (Edge e in n.RightEdges) e.Active = false; foreach (Edge e in n.LeftEdges) e.Active = false; RemainingNodes.Remove(n); } } Edges = AcyclicEdges; foreach (Edge e in Edges) e.Active = true; }
public ColorGradientWidget(GCodeFile gcodeFileTest) : base(FlowDirection.TopToBottom) { BackgroundColor = new RGBA_Bytes(0, 0, 0, 120); HashSet<float> speeds = new HashSet<float>(); PrinterMachineInstruction previousInstruction = gcodeFileTest.Instruction(0); for (int i = 1; i < gcodeFileTest.LineCount; i++) { PrinterMachineInstruction instruction = gcodeFileTest.Instruction(i); if (instruction.EPosition > previousInstruction.EPosition && (instruction.Line.IndexOf('X') != -1 || instruction.Line.IndexOf('Y') != -1)) { speeds.Add((float)instruction.FeedRate); } previousInstruction = instruction; } ExtrusionColors extrusionColors = new ExtrusionColors(); speeds.Select(speed => extrusionColors.GetColorForSpeed(speed)).ToArray(); if(speeds.Count <= 0) { // There are no paths so don't generate the rest of the widget. return; } float min = speeds.Min(); float max = speeds.Max(); int maxItems = Math.Min(7, speeds.Count()); int count = maxItems - 1; float increment = (max - min) / count; int index = 0; int[] rangeValues; if (speeds.Count < 8) { rangeValues = speeds.Select(s => (int)s).OrderBy(i => i).ToArray(); } else { rangeValues = Enumerable.Range(0, maxItems).Select(x => (int)(min + increment * index++)).ToArray(); } RGBA_Bytes[] speedColors = rangeValues.OrderBy(s => s).Select(speed => extrusionColors.GetColorForSpeed(speed)).ToArray(); for (int i = 0; i < speedColors.Length; i++) { RGBA_Bytes color = speedColors[i]; int speed = rangeValues[i]; GuiWidget colorWidget = new GuiWidget(); colorWidget.Width = 20; colorWidget.Height = 20; colorWidget.BackgroundColor = color; colorWidget.Margin = new BorderDouble(2); double feedRateToMMPerSecond = speed / 60; ColorToSpeedWidget colorToSpeedWidget = new ColorToSpeedWidget(colorWidget, feedRateToMMPerSecond); this.AddChild(colorToSpeedWidget); } Margin = new BorderDouble(5, 5, 200, 50); HAnchor |= Agg.UI.HAnchor.ParentLeft; VAnchor = Agg.UI.VAnchor.ParentTop; }
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); }
private void addEntryToolStripMenuItem_Click(object sender, EventArgs e) { if (_enumType != null) { long value = 0; HashSet<long> values = new HashSet<long>(); string name = GenerateName(); if (name != null) { foreach (EnumParserTypeEntry ent in _enumType.Entries) { if (!values.Contains(ent.Value)) { values.Add(ent.Value); } } if (!_enumType.IsFlags) { if (values.Count > 0) { value = values.Max() + 1; } } else { // Find the next positive enum value for simplicity for (value = 1; value < 0x4000000000000001L; value <<= 1) { if (!values.Contains(value)) { break; } } } EnumParserTypeEntry entry = new EnumParserTypeEntry(name, value); _enumType.AddEntry(entry); AddEnumEntryToList(entry, true); } } }
public override void Activate(Actor self, Order order, SupportPowerManager manager) { base.Activate(self, order, manager); activeArmaments = Armaments.Where(x => !x.IsTraitDisabled).ToHashSet(); var armamentturrets = activeArmaments.Select(x => x.Info.Turret).ToHashSet(); // TODO: Fix this when upgradable Turreteds arrive. turrets = self.TraitsImplementing<Turreted>().Where(x => armamentturrets.Contains(x.Name)).ToHashSet(); if (self.Owner.IsAlliedWith(self.World.RenderPlayer)) Game.Sound.Play(FireArmamentPowerInfo.LaunchSound); else Game.Sound.Play(FireArmamentPowerInfo.IncomingSound); target = Target.FromCell(self.World, order.TargetLocation); enabled = true; // TODO: Estimate the projectile travel time somehow estimatedTicks = activeArmaments.Max(x => x.FireDelay); if (FireArmamentPowerInfo.CameraActor != null) { var camera = self.World.CreateActor(false, FireArmamentPowerInfo.CameraActor, new TypeDictionary { new LocationInit(order.TargetLocation), new OwnerInit(self.Owner), }); camera.QueueActivity(new Wait(FireArmamentPowerInfo.CameraSpawnAdvance + FireArmamentPowerInfo.CameraRemoveDelay)); camera.QueueActivity(new RemoveSelf()); Action addCamera = () => self.World.AddFrameEndTask(w => w.Add(camera)); self.World.AddFrameEndTask(w => w.Add(new DelayedAction(estimatedTicks - FireArmamentPowerInfo.CameraSpawnAdvance, addCamera))); } if (FireArmamentPowerInfo.DisplayBeacon) { var beacon = new Beacon( order.Player, self.World.Map.CenterOfCell(order.TargetLocation), FireArmamentPowerInfo.BeaconPaletteIsPlayerPalette, FireArmamentPowerInfo.BeaconPalette, FireArmamentPowerInfo.BeaconImage, FireArmamentPowerInfo.BeaconPoster, FireArmamentPowerInfo.BeaconPosterPalette, FireArmamentPowerInfo.ArrowSequence, FireArmamentPowerInfo.CircleSequence, FireArmamentPowerInfo.ClockSequence, () => FractionComplete); Action removeBeacon = () => self.World.AddFrameEndTask(w => { w.Remove(beacon); beacon = null; }); self.World.AddFrameEndTask(w => { w.Add(beacon); w.Add(new DelayedAction(estimatedTicks - FireArmamentPowerInfo.BeaconRemoveAdvance, removeBeacon)); }); } ticks = 0; }
/// <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; }
private GraphicsMode GetDefaultGraphicsMode() { int[] aaLevels = new int[] { 0, 2, 4, 6, 8, 16 }; HashSet<GraphicsMode> availGraphicsModes = new HashSet<GraphicsMode>(new GraphicsModeComparer()); foreach (int samplecount in aaLevels) { GraphicsMode mode = new GraphicsMode(32, 24, 0, samplecount, new OpenTK.Graphics.ColorFormat(0), 2, false); if (!availGraphicsModes.Contains(mode)) availGraphicsModes.Add(mode); } int highestAALevel = MathF.RoundToInt(MathF.Log(MathF.Max(availGraphicsModes.Max(m => m.Samples), 1.0f), 2.0f)); int targetAALevel = highestAALevel; if (DualityApp.AppData.MultisampleBackBuffer) { switch (DualityApp.UserData.AntialiasingQuality) { case AAQuality.High: targetAALevel = highestAALevel; break; case AAQuality.Medium: targetAALevel = highestAALevel / 2; break; case AAQuality.Low: targetAALevel = highestAALevel / 4; break; case AAQuality.Off: targetAALevel = 0; break; } } else { targetAALevel = 0; } int targetSampleCount = MathF.RoundToInt(MathF.Pow(2.0f, targetAALevel)); return availGraphicsModes.LastOrDefault(m => m.Samples <= targetSampleCount) ?? availGraphicsModes.Last(); }