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);
    }
Exemple #2
0
 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());
        }
Exemple #4
0
        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;
        }
Exemple #6
0
        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));
            }
        }
Exemple #11
0
        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);
        }
Exemple #13
0
        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);
        }
Exemple #15
0
        // 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();
        }
Exemple #16
0
        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);
        }
Exemple #17
0
        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;
            }
        }
Exemple #18
0
        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);
        }
Exemple #19
0
        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);
        }
Exemple #20
0
    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());
    }
Exemple #21
0
        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;
        }
Exemple #22
0
        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);
                }
            }
        }
Exemple #24
0
        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);
        }
Exemple #25
0
        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;
        }
Exemple #26
0
        /* 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());
        }
Exemple #28
0
        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);
        }
Exemple #29
0
        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);
        }
Exemple #30
0
        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);
        }
Exemple #31
0
        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();
        }
Exemple #32
0
        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.");
        }
Exemple #33
0
        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;
        }
Exemple #35
0
            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());
            }
Exemple #36
0
        /// <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]";
                }
            }
        }
Exemple #39
0
    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");
        }
    }
Exemple #40
0
        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());
        }
Exemple #41
0
        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;
                }
            }
        }
Exemple #43
0
        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();
        }
Exemple #47
0
        //=====================================================================

        /// <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);
        }
Exemple #48
0
        /// <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;
            }
        }
Exemple #49
0
        /// <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();
        }
Exemple #50
0
        /// <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);
        }
Exemple #52
0
        /// <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;
		}
Exemple #57
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();
		}