public long GetNextAvailableLong(List<long> values, bool returnZero)
        {
            if (values == null || !values.Any())
            {
                if (returnZero)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }

            HashSet<long> hashSetValues = new HashSet<long>(values);

            long x = hashSetValues.Min();

            while (hashSetValues.Any(m => m == x))
            {
                x++;
                if (x == 0 && !returnZero)
                {
                    x++;
                }
            }

            return x;
        }
    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);
    }
        public void MoveLanesRight(int fromLane)
        {
            int nextGap = _gaps?.Min(lane => lane > fromLane ? lane : null) ?? int.MaxValue;

            if (_revisionLane >= fromLane && _revisionLane < nextGap)
            {
                ++_revisionLane;
            }

            Validates.NotNull(_segmentLanes);
            RevisionGraphSegment[] segmentsToBeMoved = _segmentLanes.Where(keyValue => keyValue.Value >= fromLane && keyValue.Value < nextGap)
                                                       .Select(keyValue => keyValue.Key)
                                                       .ToArray();
            if (!segmentsToBeMoved.Any())
            {
                return;
            }

            _gaps ??= new();
            _gaps.Add(fromLane);
            if (nextGap < int.MaxValue)
            {
                _gaps.Remove(nextGap);
            }
            else
            {
                ++_laneCount;
            }

            foreach (RevisionGraphSegment segment in segmentsToBeMoved)
            {
                ++_segmentLanes[segment];
            }
        }
        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());
        }
Esempio n. 5
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);
        }
Esempio n. 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());
        }
Esempio n. 7
0
        /// <summary>
        /// Generic path finding. Works on any map type.
        /// </summary>
        /// <returns>A list of paths to take to move from the start node to the goal node using the minimum number of paths, or null if no such list exists.</returns>
        public static List<Path> Find(IGameMap map, IMapNode start, IMapNode goal)
        {
            if (start == goal)
                return new List<Path>();
            Dictionary<IMapNode, int> distance = new Dictionary<IMapNode, int>();
            Dictionary<IMapNode, Path> previous = new Dictionary<IMapNode, Path>();

            ICollection<IMapNode> unvisited = new HashSet<IMapNode>();

            foreach (IMapNode node in map.Nodes)
            {
                distance.Add(node, Int32.MaxValue);
                previous.Add(node, null);
                unvisited.Add(node);
            }

            distance[start] = 0;

            while (unvisited.Count > 0)
            {
                IMapNode currentNode = unvisited.First(x => distance[x] == unvisited.Min(y => distance[y]));
                unvisited.Remove(currentNode);

                if (currentNode == goal)
                    break;

                foreach (Path p in map.GetPathsFrom(currentNode))
                {
                    IMapNode neighbor = p.To;
                    int alternateDistance = distance[currentNode] + 1;
                    if (alternateDistance < distance[neighbor])
                    {
                        distance[neighbor] = alternateDistance;
                        previous[neighbor] = p;
                    }
                }
            }

            List<Path> path = new List<Path>();
            Path prevPath = previous[goal];

            do
            {
                path.Insert(0, prevPath);
                prevPath = previous[prevPath.From];
            } while (prevPath != null);

            return path;
        }
        public void FindSmallestMemberOfChain()
        {
            var chainLength = GetChainLength(402170);
            chainLength.Should().Be(65);
            var chain = new HashSet<long>();
            long startingNumber = 402170;

            long currentNumber = startingNumber;
            while (!chain.Contains(currentNumber))
            {
                chain.Add(currentNumber);
                var factors = FactorHelper.GetProperFactorsOf(currentNumber);
                var sum = factors.Sum();
                currentNumber = sum;
            }

            var smallest = chain.Min();
            Console.WriteLine("Smallest member of longest chain: {0}", smallest);
        }
        protected IEnumerable <int> EnumerateLevels(int start = 99, int end = 0)
        {
            var decrementing         = start > end;
            var increment            = decrementing ? -1 : 1;
            var knownLevelsPopulated = KnownLevels.Any();

            var maxKnown = knownLevelsPopulated ? KnownLevels.Max() : 0;
            var minKnown = knownLevelsPopulated ? KnownLevels.Min() : 0;


            for (var i = start; decrementing?i >= end : i <= end; i += increment)
            {
                if (knownLevelsPopulated && (i >= minKnown || i <= maxKnown))
                {
                    if (KnownLevels.Contains(i))
                    {
                        yield return(i);
                    }
                    continue;
                }
                yield return(i);
            }
        }
Esempio n. 10
0
 public void Draw(IPixelSet pixelSet, IDrawingArea drawingArea)
 {
     if (!afterClick)
     {
         return;
     }
     if (allPoints == null)
     {
         this.pixelSet    = pixelSet;
         allPoints        = new HashSet <KeyValuePair <int, int> >(new Comparer());
         drawingPoints    = new HashSet <KeyValuePair <int, int> >(new Comparer());
         this.drawingArea = drawingArea;
         startFill();
         minY = allPoints.Min(x => x.Value);
         maxY = allPoints.Max(x => x.Value);
         ThreadPool.QueueUserWorkItem(fedos);
     }
     lock (drawingPoints)
         foreach (var x in drawingPoints)
         {
             pixelSet.FillCell(x.Key, x.Value);
         }
 }
        private static void GetMaxAndSecondMaxUsingHashing(int[] arr)
        {
            HashSet <int> trackMax = new HashSet <int>();
            int           max1 = -1, max2 = -1, size = arr.Length;

            for (int i = 0; i < size; i++)
            {
                trackMax.Add(arr[i]);
                if (trackMax.Count > 2)
                {
                    trackMax.Remove(trackMax.Min());
                }
            }

            if (trackMax.Count == 2)
            {
                Console.WriteLine("The max two numbers are :{0}, {1}", trackMax.Max(), trackMax.Min());
            }
            else
            {
                Console.WriteLine("The max two numbers are :{0}, {1}", trackMax.Max(), -1);
            }
        }
        public override __long__[] GetDistances(int start)
        {
            var dist = GetInitializedDistances(start);
            var vSet = new HashSet <int>(Enumerable.Range(0, V));

            while (vSet.Count > 0)
            {
                var min  = vSet.Min(x => dist[x]);
                var from = vSet.First(x => dist[x] == min);
                vSet.Remove(from);
                if (dist[from] == Infinity)
                {
                    break;
                }

                foreach (var edge in Edges[from])
                {
                    dist[edge.To] = Math.Min(dist[edge.To], dist[from] + edge.Cost);
                }
            }

            return(dist);
        }
Esempio n. 13
0
        // Проверка факта, что нумерация вершин начинается с 0 и идет по порядку.
        private static int CountVerteces(List <Edge> edges)
        {
            HashSet <int> uniqueLabel = new HashSet <int>();

            foreach (var edge in edges)
            {
                uniqueLabel.Add(edge.V1);
                uniqueLabel.Add(edge.V2);
            }
            int minValue = uniqueLabel.Min();

            if (minValue != 0)
            {
                throw new FormatException("Индексация вершин должна начинаться с нуля");
            }
            int n = uniqueLabel.Max() + 1;

            if (n != uniqueLabel.Count)
            {
                throw new FormatException("Индексация вершин должна идти по порядку");
            }
            return(n);
        }
Esempio n. 14
0
        public static int Solution(int[] A)
        {
            int totalSum = 0;

            var results = new HashSet <int>();

            foreach (var item in A)
            {
                totalSum += item;
            }

            int prev = A[0];
            int next = totalSum - prev;

            for (int i = 1; i < A.Length; i++)
            {
                results.Add(ReturnModulus(prev, next));
                prev += A[i];
                next  = totalSum - prev;
            }

            return(results.Min());
        }
Esempio n. 15
0
        // �������� �����, ��� ��������� ������ ���������� � 0 � ���� �� �������.
        private static int CountVerteces(List <Edge> edges)
        {
            HashSet <int> uniqueLabel = new HashSet <int>();

            foreach (var edge in edges)
            {
                uniqueLabel.Add(edge.V1);
                uniqueLabel.Add(edge.V2);
            }
            int minValue = uniqueLabel.Min();

            if (minValue != 0)
            {
                throw new FormatException("���������� ������ ������ ���������� � ����");
            }
            int n = uniqueLabel.Max() + 1;

            if (n != uniqueLabel.Count)
            {
                throw new FormatException("���������� ������ ������ ���� �� �������");
            }
            return(n);
        }
        public static HashSet <short> NewSetWithMinimum(this HashSet <short> set, short value)
        {
            var minimum = set.Min();

            if (value == minimum)
            {
                return(set);
            }
            set.Add(value);

            if (value < minimum)
            {
                var rangeToAdd = Enumerable.Range(value, minimum - value).Select(i => (short)i);
                set.UnionWith(rangeToAdd);
            }
            else
            {
                var rangeToSubtract = Enumerable.Range(minimum, value - minimum).Select(i => (short)i);
                set.ExceptWith(rangeToSubtract);
            }

            return(set);
        }
Esempio n. 17
0
        public IList <string> FindAllConcatenatedWordsInADict(string[] words)
        {
            var result = new List <string>();

            var wordsSet = new HashSet <string>(words.Where(w => w != string.Empty));

            if (wordsSet.Count == 0)
            {
                return(result);
            }

            minWordLen = wordsSet.Min(w => w.Length);
            maxWordLen = wordsSet.Max(w => w.Length);

            foreach (var w in wordsSet)
            {
                if (CheckWord(w, wordsSet))
                {
                    result.Add(w);
                }
            }

            return(result);
        }
Esempio n. 18
0
        public JObject CreatePage(Uri indexUri, List <JObject> packageDetails)
        {
            var versionSet = new HashSet <NuGetVersion>(packageDetails.Select(GetPackageVersion));
            var lower      = versionSet.Min().ToIdentityString().ToLowerInvariant();
            var upper      = versionSet.Max().ToIdentityString().ToLowerInvariant();

            var json = JsonUtility.Create(indexUri, $"page/{lower}/{upper}", "catalog:CatalogPage");

            json.Add("commitId", _context.CommitId.ToString().ToLowerInvariant());
            json.Add("commitTimeStamp", DateTimeOffset.UtcNow.GetDateString());

            json.Add("count", packageDetails.Count);

            json.Add("parent", indexUri.AbsoluteUri);
            json.Add("lower", lower);
            json.Add("upper", upper);

            // Order and add all items
            var itemsArray = new JArray(packageDetails.OrderBy(GetPackageVersion));

            json.Add("items", itemsArray);

            return(JsonLDTokenComparer.Format(json, recurse: false));
        }
Esempio n. 19
0
        private double TwoForThree(double currentSum, string[] items, HashSet <string> availableForDiscount, Dictionary <string, double> prices)
        {
            var validForDiscount = new HashSet <double>();
            int counter          = 0;

            for (int i = 0; i < items.Length; i++)
            {
                if (availableForDiscount.Contains(items[i]))
                {
                    validForDiscount.Add(prices[items[i]]);
                    counter++;
                }

                if (counter == 3)
                {
                    currentSum = currentSum - validForDiscount.Min();
                    validForDiscount.Clear();
                    counter = 0;
                }
            }


            return(currentSum);
        }
Esempio n. 20
0
        /*
         * Given two int values, return whichever value is larger.
         * However if the two values have the same remainder when divided by 5,
         * then the return the smaller value. However, in all cases, if the two
         * values are the same, return 0.
         *
         * maxMod5(25, 15) → 15
         * maxMod5(6, 2) → 6
         * maxMod5(3, 3) → 0
         */
        public static int maxMod5(params int[] values)
        {
            HashSet <int> vals = new HashSet <int>();
            HashSet <int> mods = new HashSet <int>();

            foreach (int val in values)
            {
                vals.Add(val);
                mods.Add(val % 5);
            }

            if (vals.Count < 2)
            {
                return(0);
            }
            else if (mods.Count < 2)
            {
                return(vals.Min());
            }
            else
            {
                return(vals.Max());
            }
        }
Esempio n. 21
0
 public int GetId()
 {
     return(cells.Min(c => c.Id));
 }
Esempio n. 22
0
        public void HashSetExtensions_Min_ThrowsExceptionIfHashSetIsEmpty()
        {
            var set = new HashSet<Int32>();

            Assert.That(() => set.Min(),
                Throws.TypeOf<InvalidOperationException>());
        }
Esempio n. 23
0
        // Returns a stack of nodes representing the path from start to goal.
        // Popping elements off the stack yields the correct sequence of moves
        // in order.
        public Stack<MazeNode> AStarSearch(MazeNode start, MazeNode goal)
        {
            HashSet<MazeNode> closed = new HashSet<MazeNode>();
            HashSet<MazeNode> open = new HashSet<MazeNode>();
            MazeNode current;
            ArrayList children;
            int GScoreEstimate;
            start.g = 0;
            start.h = start.manhattanDistance(goal);
            start.f = start.g + start.h;
            start.a_star_parent = start;
            open.Add(start);

            //While there are adjacent, unexplored nodes to search
            while (open.Count > 0)
            {
                current = open.Min();
                //If we've reached our goal
                if (current == goal)
                {
                    //Retrieve the path we took via a stack
                    Stack<MazeNode> path_to_goal = new Stack<MazeNode>();
                    while (current.a_star_parent != current)
                    {
                        path_to_goal.Push(current);
                        current = current.a_star_parent;
                    }
                    path_to_goal.Push(current);
                    return path_to_goal;
                }

                //Else continue our search
                open.Remove(current);
                closed.Add(current);
                children = current.getAdjacentEdges();
                foreach (MazeNode child in children)
                {
                    // If we've visited this node already, skip it.
                    if (closed.Contains(child))
                    {
                        continue;
                    }

                    // g is computed as the cost it took us to get here, plus the distance between the
                    // current node and the child we're considering.
                    GScoreEstimate = (int)(current.g) + current.manhattanDistance(child);

                    // If we haven't considered this node already, or our current estimate is more optimistic
                    // than our prior estimation
                    if (!open.Contains(child) || GScoreEstimate < child.g)
                    {
                        child.g = GScoreEstimate;
                        child.f = child.g + child.manhattanDistance(goal);

                        if (!open.Contains(child))
                        {
                            open.Add(child);
                        }

                        child.a_star_parent = current;
                    }
                }
                closed.Add(current);
            }
            //Search failed, no more nodes to find on open list
            return null;
        }
Esempio n. 24
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="selectedNotes"> The note models in current selection </param>
        /// <param name="currentWorkspace"> The workspace where</param>
        /// <param name="args"></param>
        internal CustomNodeWorkspaceModel Collapse(
            IEnumerable <NodeModel> selectedNodes,
            IEnumerable <NoteModel> selectedNotes,
            WorkspaceModel currentWorkspace,
            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;

            Debug.WriteLine("Current workspace has {0} nodes and {1} connectors",
                            currentWorkspace.Nodes.Count(), currentWorkspace.Connectors.Count());

            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.InPorts.Count)
                            .Where(index => node.InPorts[index].Connectors.Any())
                            .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.OutPorts.Count)
                            .Where(index => node.OutPorts[index].Connectors.Any())
                            .SelectMany(
                                data =>
                                node.OutputNodes[data].Where(
                                    output => !selectedNodeSet.Contains(output.Item2))
                                .Select(output => Tuple.Create(node, data, output)))));

                #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 newNotes       = new List <NoteModel>();
                var newAnnotations = new List <AnnotationModel>();

                // Step 4: move all nodes and notes 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.RemoveAndDisposeNode(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();

                    // shift nodes
                    node.X = node.X - leftShift;
                    node.Y = node.Y - topMost;

                    newNodes.Add(node);
                }

                foreach (var note in selectedNotes)
                {
                    undoRecorder.RecordDeletionForUndo(note);
                    currentWorkspace.RemoveNote(note);

                    note.GUID = Guid.NewGuid();
                    note.X    = note.X - leftShift;
                    note.Y    = note.Y - topMost;
                    newNotes.Add(note);
                }

                //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.Nodes = group.DeletedModelBases;
                    newAnnotations.Add(group);
                }

                // Now all selected nodes already moved to custom workspace,
                // clear the selection.
                DynamoSelection.Instance.ClearSelection();

                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.InPorts[inputReceiverData].Name,
                            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 EFunction)
                        {
                            var func = inputReceiverNode as EFunction;
                            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 == Engine.FunctionType.InstanceMethod ||
                                funcDesc.Type == Engine.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.SetNameFromNodeNameAttribute();
                        node.Y = inputIndex * (50 + node.Height);

                        uniqueInputSenders[key] = node;

                        newNodes.Add(node);
                    }

                    ConnectorModel.Make(node, 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;

                            outportList.Add(Tuple.Create(outputSenderNode, outputSenderData));

                            //Create Symbol Node
                            var node = new Output
                            {
                                Symbol = outputSenderNode.OutPorts[outputSenderData].Name,
                                X      = rightMost + 75 - leftShift
                            };

                            node.Y = i * (50 + node.Height);

                            node.SetNameFromNodeNameAttribute();

                            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.OutPorts.Count)
                                 .Where(index => !node.OutPorts[index].IsConnected)
                                 .Select(port => new { node, port })).Distinct())
                    {
                        //Create Symbol Node
                        var node = new Output
                        {
                            Symbol = hanging.node.OutPorts[hanging.port].Name,
                            X      = rightMost + 75 - leftShift
                        };
                        node.Y = i * (50 + node.Height);
                        node.SetNameFromNodeNameAttribute();

                        newNodes.Add(node);
                        ConnectorModel.Make(hanging.node, node, hanging.port, 0);

                        i++;
                    }
                }

                #endregion

                var newId = Guid.NewGuid();
                newWorkspace = new CustomNodeWorkspaceModel(
                    nodeFactory,
                    newNodes,
                    newNotes,
                    newAnnotations,
                    Enumerable.Empty <PresetModel>(),
                    currentWorkspace.ElementResolver,
                    new WorkspaceInfo()
                {
                    X           = 0,
                    Y           = 0,
                    Name        = args.Name,
                    Category    = args.Category,
                    Description = args.Description,
                    ID          = newId.ToString(),
                    FileName    = string.Empty,
                    IsVisibleInDynamoLibrary = true
                });

                newWorkspace.HasUnsavedChanges = true;

                RegisterCustomNodeWorkspace(newWorkspace);

                Debug.WriteLine("Collapsed workspace has {0} nodes and {1} connectors",
                                newWorkspace.Nodes.Count(), newWorkspace.Connectors.Count());

                var collapsedNode = CreateCustomNodeInstance(newId);
                collapsedNode.X = avgX;
                collapsedNode.Y = avgY;
                currentWorkspace.AddAndRegisterNode(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);
        }
        public void HashSetExtensions_Min_ThrowsExceptionIfHashSetIsEmpty()
        {
            var set = new HashSet<Int32>();

            set.Min();
        }
Esempio n. 26
0
        List <ILNode> ConvertToAst(List <ByteCode> body, HashSet <ExceptionHandler> ehs)
        {
            List <ILNode> ast = new List <ILNode>();

            while (ehs.Any())
            {
                ILTryCatchBlock tryCatchBlock = new ILTryCatchBlock();

                // Find the first and widest scope
                int tryStart = ehs.Min(eh => eh.TryStart.Offset);
                int tryEnd   = ehs.Where(eh => eh.TryStart.Offset == tryStart).Max(eh => eh.TryEnd.Offset);
                var handlers = ehs.Where(eh => eh.TryStart.Offset == tryStart && eh.TryEnd.Offset == tryEnd).ToList();

                // Cut all instructions up to the try block
                {
                    int tryStartIdx;
                    for (tryStartIdx = 0; body[tryStartIdx].Offset != tryStart; tryStartIdx++)
                    {
                        ;
                    }
                    ast.AddRange(ConvertToAst(body.CutRange(0, tryStartIdx)));
                }

                // Cut the try block
                {
                    HashSet <ExceptionHandler> nestedEHs = new HashSet <ExceptionHandler>(ehs.Where(eh => (tryStart <= eh.TryStart.Offset && eh.TryEnd.Offset < tryEnd) || (tryStart < eh.TryStart.Offset && eh.TryEnd.Offset <= tryEnd)));
                    ehs.ExceptWith(nestedEHs);
                    int tryEndIdx;
                    for (tryEndIdx = 0; tryEndIdx < body.Count && body[tryEndIdx].Offset != tryEnd; tryEndIdx++)
                    {
                        ;
                    }
                    tryCatchBlock.TryBlock = new ILBlock(ConvertToAst(body.CutRange(0, tryEndIdx), nestedEHs));
                }

                // Cut all handlers
                tryCatchBlock.CatchBlocks = new List <ILTryCatchBlock.CatchBlock>();
                foreach (ExceptionHandler eh in handlers)
                {
                    int startIndex;
                    for (startIndex = 0; body[startIndex].Offset != eh.HandlerStart.Offset; startIndex++)
                    {
                        ;
                    }
                    int endInclusiveIndex;
                    if (eh.HandlerEnd == null)
                    {
                        endInclusiveIndex = body.Count - 1;
                    }
                    // Note that the end(exclusive) instruction may not necessarly be in our body
                    else
                    {
                        for (endInclusiveIndex = 0; body[endInclusiveIndex].Next.Offset != eh.HandlerEnd.Offset; endInclusiveIndex++)
                        {
                            ;
                        }
                    }
                    int count = 1 + endInclusiveIndex - startIndex;
                    HashSet <ExceptionHandler> nestedEHs = new HashSet <ExceptionHandler>(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < eh.HandlerEnd.Offset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= eh.HandlerEnd.Offset)));
                    ehs.ExceptWith(nestedEHs);
                    List <ILNode> handlerAst = ConvertToAst(body.CutRange(startIndex, count), nestedEHs);
                    if (eh.HandlerType == ExceptionHandlerType.Catch)
                    {
                        ILTryCatchBlock.CatchBlock catchBlock = new ILTryCatchBlock.CatchBlock()
                        {
                            ExceptionType = eh.CatchType,
                            Body          = handlerAst
                        };
                        // Handle the automatically pushed exception on the stack
                        ByteCode ldexception = ldexceptions[eh];
                        if (ldexception.StoreTo.Count == 0)
                        {
                            throw new Exception("Exception should be consumed by something");
                        }
                        else if (ldexception.StoreTo.Count == 1)
                        {
                            ILExpression first = catchBlock.Body[0] as ILExpression;
                            if (first != null &&
                                first.Code == ILCode.Pop &&
                                first.Arguments[0].Code == ILCode.Ldloc &&
                                first.Arguments[0].Operand == ldexception.StoreTo[0])
                            {
                                // The exception is just poped - optimize it all away;
                                catchBlock.ExceptionVariable = null;
                                catchBlock.Body.RemoveAt(0);
                            }
                            else
                            {
                                catchBlock.ExceptionVariable = ldexception.StoreTo[0];
                            }
                        }
                        else
                        {
                            ILVariable exTemp = new ILVariable()
                            {
                                Name = "ex_" + eh.HandlerStart.Offset.ToString("X2"), IsGenerated = true
                            };
                            catchBlock.ExceptionVariable = exTemp;
                            foreach (ILVariable storeTo in ldexception.StoreTo)
                            {
                                catchBlock.Body.Insert(0, new ILExpression(ILCode.Stloc, storeTo, new ILExpression(ILCode.Ldloc, exTemp)));
                            }
                        }
                        tryCatchBlock.CatchBlocks.Add(catchBlock);
                    }
                    else if (eh.HandlerType == ExceptionHandlerType.Finally)
                    {
                        tryCatchBlock.FinallyBlock = new ILBlock(handlerAst);
                    }
                    else if (eh.HandlerType == ExceptionHandlerType.Fault)
                    {
                        tryCatchBlock.FaultBlock = new ILBlock(handlerAst);
                    }
                    else
                    {
                        // TODO: ExceptionHandlerType.Filter
                    }
                }

                ehs.ExceptWith(handlers);

                ast.Add(tryCatchBlock);
            }

            // Add whatever is left
            ast.AddRange(ConvertToAst(body));

            return(ast);
        }
Esempio n. 27
0
        static void Main(string[] args)
        {
            int           offset  = 100;
            StreamReader  sr      = new StreamReader("input12.txt");
            List <Recipe> notes   = new List <Recipe>();
            string        initial = sr.ReadLine(); sr.ReadLine();     //remove empty

            initial = initial.Substring(initial.IndexOf(':') + 2);
            for (int i = 0; i < initial.Length; i++)
            {
                if (initial[i] == '#')
                {
                    pots.Add(i + offset);
                }
            }
            while (sr.Peek() != -1)
            {
                Recipe tmp = new Recipe();
                tmp.mostLeft  = sr.Read() == '#' ? true : false;
                tmp.left      = sr.Read() == '#' ? true : false;
                tmp.current   = sr.Read() == '#' ? true : false;
                tmp.right     = sr.Read() == '#' ? true : false;
                tmp.mostRight = sr.Read() == '#' ? true : false;
                sr.Read(); sr.Read(); sr.Read(); sr.Read(); //" => "
                tmp.result = sr.Read() == '#' ? true : false;
                sr.Read();                                  //\n
                notes.Add(tmp);
            }

            //PART1
            for (int i = 0; i < 20; i++)
            {
                HashSet <long> nextGenPots = new HashSet <long>();
                for (int j = 2; j < 298; j++)
                {
                    Recipe match = new Recipe(pVal(j - 2), pVal(j - 1), pVal(j), pVal(j + 1), pVal(j + 2), true);
                    if (notes.Contains(match))
                    {
                        nextGenPots.Add(j);
                    }
                }
                pots = new HashSet <long>(nextGenPots);
            }
            int result = 0;

            foreach (int pot in pots)
            {
                result += pot - offset;
            }
            Console.WriteLine(result);
            //PART1

            //PART2
            pots = new HashSet <long>();
            for (int i = 0; i < initial.Length; i++)
            {
                if (initial[i] == '#')
                {
                    pots.Add(i + offset);
                }
            }

            List <List <int> > set      = new List <List <int> >(); //every observed distribution
            List <int>         movement = new List <int>();         //how much first plant moved comparing to previous generation
            long last     = pots.First();
            int  eachMove = 0;
            int  move     = 0;
            long x;                           //need to remember when break occurs

            for (x = 0; x < 50000000000; x++) //should break much faster - if not, full simulation is performed(VERY SLOW)
            {
                HashSet <long> nextGenPots = new HashSet <long>();
                long           min         = pots.Min() - 3; //minimise search range
                long           max         = pots.Max() + 3; //minimise search range
                List <int>     currentSet  = new List <int>();
                bool           first       = false;
                int            diff        = 0;
                for (long j = min; j < max; j++)
                {
                    Recipe match = new Recipe(pVal(j - 2), pVal(j - 1), pVal(j), pVal(j + 1), pVal(j + 2), true);
                    if (notes.Contains(match))
                    {
                        nextGenPots.Add(j);                //this generation
                        if (!first)                        //calculate relative difference between each plant
                        {
                            currentSet.Add(0);
                            first = true;
                        }
                        else
                        {
                            currentSet.Add(diff);
                            diff = 0;
                        }
                    }
                    diff++;
                }
                pots = new HashSet <long>(nextGenPots);               //update pots
                bool breakFor = false;
                foreach (List <int> s in set)
                {
                    if (s.SequenceEqual(currentSet))                    //ordered comparison
                    {
                        int lastMatch = set.IndexOf(s);
                        move = (int)(x - lastMatch);                        //how many generations before the same distribution
                        for (int k = lastMatch; k < x; k++)
                        {
                            eachMove += movement[k];                            //how much plants moved
                        }
                        breakFor = true;
                    }
                }
                if (breakFor)
                {
                    break;
                }

                set.Add(currentSet);                      //for pattern finding

                movement.Add((int)(pots.First() - last)); //calcualte movement
                last = pots.First();                      //assign new last
            }

            long result2 = 0;
            long diffr   = (50000000000 - x - 1) * eachMove;          //assuming move == 1

            foreach (long pot in pots)
            {
                result2 += (pot + diffr) - offset;
            }
            Console.WriteLine(result2);
            //PART2
        }
Esempio n. 28
0
        List<ILNode> ConvertToAst(List<ByteCode> body, HashSet<ExceptionHandler> ehs)
        {
            List<ILNode> ast = new List<ILNode>();

            while (ehs.Any()) {
                ILTryCatchBlock tryCatchBlock = new ILTryCatchBlock();

                // Find the first and widest scope
                int tryStart = ehs.Min(eh => eh.TryStart.Offset);
                int tryEnd   = ehs.Where(eh => eh.TryStart.Offset == tryStart).Max(eh => eh.TryEnd.Offset);
                var handlers = ehs.Where(eh => eh.TryStart.Offset == tryStart && eh.TryEnd.Offset == tryEnd).ToList();

                // Cut all instructions up to the try block
                {
                    int tryStartIdx;
                    for (tryStartIdx = 0; body[tryStartIdx].Offset != tryStart; tryStartIdx++);
                    ast.AddRange(ConvertToAst(body.CutRange(0, tryStartIdx)));
                }

                // Cut the try block
                {
                    HashSet<ExceptionHandler> nestedEHs = new HashSet<ExceptionHandler>(ehs.Where(eh => (tryStart <= eh.TryStart.Offset && eh.TryEnd.Offset < tryEnd) || (tryStart < eh.TryStart.Offset && eh.TryEnd.Offset <= tryEnd)));
                    ehs.ExceptWith(nestedEHs);
                    int tryEndIdx;
                    for (tryEndIdx = 0; tryEndIdx < body.Count && body[tryEndIdx].Offset != tryEnd; tryEndIdx++);
                    tryCatchBlock.TryBlock = new ILBlock(ConvertToAst(body.CutRange(0, tryEndIdx), nestedEHs));
                }

                // Cut all handlers
                tryCatchBlock.CatchBlocks = new List<ILTryCatchBlock.CatchBlock>();
                foreach(ExceptionHandler eh in handlers) {
                    int startIndex;
                    for (startIndex = 0; body[startIndex].Offset != eh.HandlerStart.Offset; startIndex++);
                    int endInclusiveIndex;
                    // Note that the end(exclusiove) instruction may not necessarly be in our body
                    for (endInclusiveIndex = 0; body[endInclusiveIndex].Next.Offset != eh.HandlerEnd.Offset; endInclusiveIndex++);
                    int count = 1 + endInclusiveIndex - startIndex;
                    HashSet<ExceptionHandler> nestedEHs = new HashSet<ExceptionHandler>(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < eh.HandlerEnd.Offset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= eh.HandlerEnd.Offset)));
                    ehs.ExceptWith(nestedEHs);
                    List<ILNode> handlerAst = ConvertToAst(body.CutRange(startIndex, count), nestedEHs);
                    if (eh.HandlerType == ExceptionHandlerType.Catch) {
                        tryCatchBlock.CatchBlocks.Add(new ILTryCatchBlock.CatchBlock() {
                            ExceptionType = eh.CatchType,
                            Body = handlerAst
                        });
                    } else if (eh.HandlerType == ExceptionHandlerType.Finally) {
                        tryCatchBlock.FinallyBlock = new ILBlock(handlerAst);
                    } else {
                        // TODO
                    }
                }

                ehs.ExceptWith(handlers);

                ast.Add(tryCatchBlock);
            }

            // Add whatever is left
            ast.AddRange(ConvertToAst(body));

            return ast;
        }
Esempio n. 29
0
        List <ILNode> ConvertToAst(List <ByteCode> body, HashSet <ExceptionHandler> ehs)
        {
            List <ILNode> ast = new List <ILNode>();

            while (ehs.Any())
            {
                ILTryCatchBlock tryCatchBlock = new ILTryCatchBlock();

                // Find the first and widest scope
                int tryStart = ehs.Min(eh => eh.TryStart.Offset);
                int tryEnd   = ehs.Where(eh => eh.TryStart.Offset == tryStart).Max(eh => eh.TryEnd.Offset);
                var handlers = ehs.Where(eh => eh.TryStart.Offset == tryStart && eh.TryEnd.Offset == tryEnd).OrderBy(eh => eh.TryStart.Offset).ToList();

                // Remember that any part of the body migt have been removed due to unreachability

                // Cut all instructions up to the try block
                {
                    int tryStartIdx = 0;
                    while (tryStartIdx < body.Count && body[tryStartIdx].Offset < tryStart)
                    {
                        tryStartIdx++;
                    }
                    ast.AddRange(ConvertToAst(body.CutRange(0, tryStartIdx)));
                }

                // Cut the try block
                {
                    HashSet <ExceptionHandler> nestedEHs = new HashSet <ExceptionHandler>(ehs.Where(eh => (tryStart <= eh.TryStart.Offset && eh.TryEnd.Offset < tryEnd) || (tryStart < eh.TryStart.Offset && eh.TryEnd.Offset <= tryEnd)));
                    ehs.ExceptWith(nestedEHs);
                    int tryEndIdx = 0;
                    while (tryEndIdx < body.Count && body[tryEndIdx].Offset < tryEnd)
                    {
                        tryEndIdx++;
                    }
                    tryCatchBlock.TryBlock = new ILBlock(ConvertToAst(body.CutRange(0, tryEndIdx), nestedEHs));
                }

                // Cut all handlers
                tryCatchBlock.CatchBlocks = new List <ILTryCatchBlock.CatchBlock>();
                foreach (ExceptionHandler eh in handlers)
                {
                    int handlerEndOffset = eh.HandlerEnd == null ? methodDef.Body.CodeSize : eh.HandlerEnd.Offset;
                    int startIdx         = 0;
                    while (startIdx < body.Count && body[startIdx].Offset < eh.HandlerStart.Offset)
                    {
                        startIdx++;
                    }
                    int endIdx = 0;
                    while (endIdx < body.Count && body[endIdx].Offset < handlerEndOffset)
                    {
                        endIdx++;
                    }
                    HashSet <ExceptionHandler> nestedEHs = new HashSet <ExceptionHandler>(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < handlerEndOffset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= handlerEndOffset)));
                    ehs.ExceptWith(nestedEHs);
                    List <ILNode> handlerAst = ConvertToAst(body.CutRange(startIdx, endIdx - startIdx), nestedEHs);
                    if (eh.HandlerType == ExceptionHandlerType.Catch)
                    {
                        ILTryCatchBlock.CatchBlock catchBlock = new ILTryCatchBlock.CatchBlock()
                        {
                            ExceptionType = eh.CatchType,
                            Body          = handlerAst
                        };
                        // Handle the automatically pushed exception on the stack
                        ByteCode ldexception = ldexceptions[eh];
                        if (ldexception.StoreTo == null || ldexception.StoreTo.Count == 0)
                        {
                            // Exception is not used
                            catchBlock.ExceptionVariable = null;
                        }
                        else if (ldexception.StoreTo.Count == 1)
                        {
                            ILExpression first = catchBlock.Body[0] as ILExpression;
                            if (first != null &&
                                first.Code == ILCode.Pop &&
                                first.Arguments[0].Code == ILCode.Ldloc &&
                                first.Arguments[0].Operand == ldexception.StoreTo[0])
                            {
                                // The exception is just poped - optimize it all away;
                                if (context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks)
                                {
                                    catchBlock.ExceptionVariable = new ILVariable()
                                    {
                                        Name = "ex_" + eh.HandlerStart.Offset.ToString("X2"), IsGenerated = true
                                    }
                                }
                                ;
                                else
                                {
                                    catchBlock.ExceptionVariable = null;
                                }
                                catchBlock.Body.RemoveAt(0);
                            }
                            else
                            {
                                catchBlock.ExceptionVariable = ldexception.StoreTo[0];
                            }
                        }
                        else
                        {
                            ILVariable exTemp = new ILVariable()
                            {
                                Name = "ex_" + eh.HandlerStart.Offset.ToString("X2"), IsGenerated = true
                            };
                            catchBlock.ExceptionVariable = exTemp;
                            foreach (ILVariable storeTo in ldexception.StoreTo)
                            {
                                catchBlock.Body.Insert(0, new ILExpression(ILCode.Stloc, storeTo, new ILExpression(ILCode.Ldloc, exTemp)));
                            }
                        }
                        tryCatchBlock.CatchBlocks.Add(catchBlock);
                    }
                    else if (eh.HandlerType == ExceptionHandlerType.Finally)
                    {
                        tryCatchBlock.FinallyBlock = new ILBlock(handlerAst);
                    }
                    else if (eh.HandlerType == ExceptionHandlerType.Fault)
                    {
                        tryCatchBlock.FaultBlock = new ILBlock(handlerAst);
                    }
                    else
                    {
                        // TODO: ExceptionHandlerType.Filter
                    }
                }

                ehs.ExceptWith(handlers);

                ast.Add(tryCatchBlock);
            }

            // Add whatever is left
            ast.AddRange(ConvertToAst(body));

            return(ast);
        }
Esempio n. 30
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;
        }
Esempio n. 31
0
        public void HashSetExtensions_Min_ReturnsMinValue()
        {
            var set = new HashSet<Int32>() { 4, 5, 6, 99, 10, 1, 12, 45 };

            var result = set.Min();

            TheResultingValue(result).ShouldBe(1);
        }
Esempio n. 32
0
            private void Initialize(string[] lines)
            {
                var clayLocations = new List <(HashSet <int> X, HashSet <int> Y)>();

                foreach (var line in lines)
                {
                    var           items = line.Split(", ");
                    HashSet <int> x     = null;
                    HashSet <int> y     = null;

                    foreach (var item in items)
                    {
                        var parts = item.Split('=');
                        if (parts[0] == "x")
                        {
                            x = GetRange(parts[1]);
                        }
                        else
                        {
                            y = GetRange(parts[1]);
                        }
                    }

                    clayLocations.Add((x, y));

                    _maxX = Math.Max(_maxX, x.Max());
                    _minY = Math.Min(_minY, y.Min());
                    _maxY = Math.Max(_maxY, y.Max());
                }

                _maxX++;
                _materials = new char[_maxX + 1, _maxY + 1];

                for (int x = 0; x <= _maxX; x++)
                {
                    for (int y = 0; y <= _maxY; y++)
                    {
                        _materials[x, y] = '.';
                    }
                }

                _materials[500, 0] = '+';

                foreach (var location in clayLocations)
                {
                    foreach (int x in location.X)
                    {
                        foreach (int y in location.Y)
                        {
                            _materials[x, y] = '#';
                        }
                    }
                }

                HashSet <int> GetRange(string part)
                {
                    var limits = part.Split("..");
                    int first  = int.Parse(limits[0]);
                    int last   = limits.Length == 1 ? first : int.Parse(limits[1]);

                    return(new HashSet <int>(Enumerable.Range(first, last - first + 1)));
                }

                _fallPoints.Add(new Point(500, 0));
            }
        public static IList<RaveDetails> GetRaveDetailsFromEventIDs(IEnumerable<Int64> eventIds)
        {
            _fb.AccessToken = _GenericAccessToken;

            string fields = "eid, name, pic_square, start_time, end_time, is_date_only, creator, update_time, location, venue";
            string eidList = string.Join(",", eventIds.ToArray());
            dynamic fqlResult = _fb.Get("fql", new { q = String.Format("SELECT {0} FROM event WHERE eid IN ({1})", fields, eidList) });
            JsonArray fqlEventResults = fqlResult.data;

            IList<RaveDetails> eventResults = new List<RaveDetails>();
            HashSet<Venue> venueResults = new HashSet<Venue>();
            HashSet<Rave> raveResults = new HashSet<Rave>();
            foreach (dynamic fqlEvent in fqlEventResults)
            {
                Int64? creatorId = fqlEvent.creator ?? 0;
                Int64? eventId = fqlEvent.eid;
                Int64? venueId = 0;
                if (fqlEvent.venue.Count > 0)
                {
                     dynamic jsonVenue = (JsonObject)fqlEvent.venue;
                     venueId = jsonVenue.id ?? 0;
                }

                Rave aRave = null;
                Venue aVenue = null;
                Owner aOwner = null;
                if (eventId != null)
                {
                    // Get the owner; no chance for duplications
                    aOwner = GetRaveOwnerFromUserID(creatorId);

                    // Before querying for the Venue, make sure we haven't already queried it
                    if (venueResults.Any(v => v.VenueID == venueId))
                    {
                        aVenue = venueResults.First(v => v.VenueID == venueId);
                    }
                    else if (fqlEvent.venue.Count > 0)
                    {
                        aVenue = GetVenueFromJsonObject((JsonObject)fqlEvent.venue);
                        if (aVenue == null)
                        {
                          // If no facebook page exists for this Venue, create a new negative ID
                          // All negative ID's therefore show that the Venue does not exist on Facebook
                                                    aVenue = new Venue();
                          using (RaveRadarContext _db = new RaveRadarContext())
                          {
                              long dbMin = _db.Venues.Min(v => v.VenueID).GetValueOrDefault(0);
                              long syncMin = venueResults.Min(v => v.VenueID).GetValueOrDefault(0);
                              aVenue.VenueID = (dbMin <= syncMin ? dbMin : syncMin) - 1;
                                                            aVenue.Name = fqlEvent.location ?? string.Empty;
                                                            aVenue.GetLocationFromGoogle(fqlEvent.location ?? string.Empty);

                                                            // If no location found, reset venue to null
                                                            if (aVenue.GetLocation() == null)
                                                            {
                                                                aVenue = null;
                                                            }
                          }
                        }

                                                if (aVenue != null)
                                                {
                                                    venueResults.Add(aVenue);
                                                }
                    }

                    // Before querying for the Rave, make sure we haven't already queried it
                    if (raveResults.Any(r => r.RaveID == eventId))
                    {
                        aRave = raveResults.First(r => r.RaveID == eventId);
                    }
                    else
                    {
                        aRave = new Rave();
                        aRave.RaveID = eventId ?? 0; // Should never happen
                        aRave.OwnerID = aOwner.OwnerID;
                        if (aVenue == null) { aRave.VenueID = null; } else { aRave.VenueID = aVenue.VenueID; }
                        aRave.Name = fqlEvent.name ?? string.Empty;
                        aRave.PicURL = fqlEvent.pic_square ?? ConfigurationManager.AppSettings["DefaultRaveIcon"].ToString();

                        aRave.StartTime = ConvertFacebookDateToLocal(fqlEvent.start_time, fqlEvent.is_date_only);
                        if (fqlEvent.end_time == null) { aRave.EndTime = null; }
                        else { aRave.EndTime = ConvertFacebookDateToLocal(fqlEvent.end_time, fqlEvent.is_date_only); }
                        aRave.IsDateOnly = fqlEvent.is_date_only;
                        aRave.Location = fqlEvent.location ?? string.Empty;
                        aRave.IsApproved = (aOwner == null ? false : aOwner.IsTrusted);
                        aRave.SubmitterID = null;
                        aRave.UpdateTime = DateTimeConvertor.FromUnixTime((double)fqlEvent.update_time);
                        raveResults.Add(aRave);
                    }
                }

                // Put all the details together to create one object
                eventResults.Add(new RaveDetails(aRave, aOwner, aVenue));
            }

            return eventResults;
        }
Esempio n. 34
0
 public Value Min() => hashSet.Min();
Esempio n. 35
0
        /// <summary>
        /// Convert the given set of bytecodes to an Ast node list.
        /// Split exception handlers into Ast try/catch blocks.
        /// </summary>
        private List<AstNode> ConvertToAst(List<ByteCode> body, HashSet<ExceptionHandler> ehs, List<ByteCodeBlock> blockStarts, int nestingLevel, Dictionary<int, ByteCode> offset2ByteCode)
        {
            var ast = new List<AstNode>();

            // Split body in blocks

            while (ehs.Any())
            {
                var tryCatchBlock = new AstTryCatchBlock(null);

                // Find the first and widest scope
                var tryStart = ehs.Min(eh => eh.StartPc);
                var tryEnd = ehs.Where(eh => eh.StartPc == tryStart).Max(eh => eh.EndPc);
                var handlers = ehs.Where(eh => (eh.StartPc == tryStart) && (eh.EndPc == tryEnd)).OrderBy(eh => eh.HandlerPc).ToList();

                // Remember that any part of the body migt have been removed due to unreachability

                // Cut all instructions up to the try block
                {
                    var tryStartIdx = 0;
                    while ((tryStartIdx < body.Count) && (body[tryStartIdx].Offset < tryStart))
                    {
                        tryStartIdx++;
                    }
                    if (tryStartIdx > 0)
                    {
                        ast.AddRange(ConvertRangeToAst(body.CutRange(0, tryStartIdx)));
                        // Make sure the block before the try block ends with an unconditional control flow
                        AddUnconditionalBranchToNext(ast, body, 0);
                    }
                }

                // Cut the try block
                {
                    var nestedEHs = new HashSet<ExceptionHandler>(
                        ehs.Where(eh => ((tryStart <= eh.StartPc) && (eh.EndPc < tryEnd)) || ((tryStart < eh.StartPc) && (eh.EndPc <= tryEnd))));
                    ehs.ExceptWith(nestedEHs);
                    var tryEndIdx = 0;
                    while ((tryEndIdx < body.Count) && (body[tryEndIdx].Offset < tryEnd))
                    {
                        tryEndIdx++;
                    }
                    var converted = ConvertToAst(body.CutRange(0, tryEndIdx), nestedEHs, blockStarts, nestingLevel + 1, offset2ByteCode);
                    tryCatchBlock.TryBlock = new AstBlock(converted.Select(x => x.SourceLocation).FirstOrDefault(), converted);
                    // Make sure the try block ends with an unconditional control flow
                    AddUnconditionalBranchToNext(tryCatchBlock.TryBlock.Body, body, 0);
                }

                // Cut all handlers
                tryCatchBlock.CatchBlocks.Clear();
                foreach (var iterator in handlers)
                {
                    var eh = iterator;
                    var handler = offset2ByteCode[eh.HandlerPc]; // body.First(x => x.Offset == eh.HandlerPc);
                    var catchType = eh.IsCatchAll ? typeSystem.Object : AsTypeReference(eh.CatchType, XTypeUsageFlags.CatchType);
                    var catchBlock = new AstTryCatchBlock.CatchBlock(handler.SourceLocation, tryCatchBlock)
                    {
                        ExceptionType = catchType,
                        Body = new List<AstNode>()
                    };

                    // Create catch "body" (actually a jump to the handler)
                    // Handle the automatically pushed exception on the stack
                    var ldexception = ldexceptions[eh];
                    catchBlock.Body.Add(new AstExpression(handler.SourceLocation, AstCode.Br, handler.Label(true)));
                    if (ldexception.StoreTo == null || ldexception.StoreTo.Count == 0)
                    {
                        // Exception is not used
                        catchBlock.ExceptionVariable = null;
                    }
                    else if (ldexception.StoreTo.Count == 1)
                    {
                        /*var first = catchBlock.Body.FirstOrDefault() as AstExpression;
                        if (first != null &&
                            first.Code == AstCode.Pop &&
                            first.Arguments[0].Code == AstCode.Ldloc &&
                            first.Arguments[0].Operand == ldexception.StoreTo[0])
                        {
                            // The exception is just poped - optimize it all away;
                            catchBlock.ExceptionVariable = new AstGeneratedVariable("ex_" + eh.HandlerPc.ToString("X2"));
                            catchBlock.Body.RemoveAt(0);
                        }
                        else*/
                        {
                            catchBlock.ExceptionVariable = ldexception.StoreTo[0];
                        }
                    }
                    else
                    {
                        var exTemp = new AstGeneratedVariable("ex_" + eh.HandlerPc.ToString("X2"), null);
                        catchBlock.ExceptionVariable = exTemp;
                        foreach (var storeTo in ldexception.StoreTo)
                        {
                            catchBlock.Body.Insert(0, new AstExpression(catchBlock.SourceLocation, AstCode.Stloc, storeTo, new AstExpression(catchBlock.SourceLocation, AstCode.Ldloc, exTemp)));
                        }
                    }
                    tryCatchBlock.CatchBlocks.Add(catchBlock);
                }

                ehs.ExceptWith(handlers);

                ast.Add(tryCatchBlock);
            }

            // Add whatever is left
            ast.AddRange(ConvertRangeToAst(body));

            return ast;
        }
Esempio n. 36
0
        private void Run(AOGraph mGraph, int start)
        {
            foreach (Node node in mGraph.Nodes)
            {
                this.costs.Add(node.Id, double.MaxValue);
            }

            this.opened.Add(mGraph.Nodes.ElementAt(start));
            this.costs[start] = 0;

            while (opened.Count > 0)
            {
                /// current => is the best node to continue search from it's sub graph
                Node current = opened.Min();
                opened.Remove(current);
                closed.Add(current);

                if (current.IsTerminal)
                {
                    this.terminals.Add(current);
                    Refresh(current.Parent);
                    continue;
                }
                else
                {
                    foreach (Operator op in current.Operators)
                    {
                        bool solveable = true;

                        foreach (Node successor in op.Ends)
                        {
                            if (!successor.IsTerminal && (successor.Operators == null || successor.Operators.Count == 0))
                            {
                                solveable = false;
                                break;
                            }
                        }

                        if (solveable)
                        {
                            foreach (Node successor in op.Ends)
                            {
                                successor.Parent = current;
                                successor.Cost   = current.Cost + G(current, successor);

                                ///Here we must to override the comparator.
                                if (!opened.Contains(successor) && !closed.Contains(successor))
                                {
                                    costs[successor.Id] = successor.Cost;
                                    opened.Add(successor);
                                }
                            }
                        }
                        else
                        {
                            Refresh(current);
                        }
                    }
                }
            }

            if (costs[start] >= double.MaxValue)
            {
                Console.WriteLine("No available paths from start = [{0:D}]", start);
                return;
            }

            Console.WriteLine("Best solution = " + this.costs[start]);
            foreach (Node node in mGraph.Nodes)
            {
                Console.WriteLine(node.Cost + ", " + costs[node.Id]);
            }
        }
Esempio n. 37
0
        List<AstNode> ConvertToAst(List<ByteCode> body, HashSet<ExceptionHandler> ehs)
        {
            var ast = new List<AstNode>();

            while (ehs.Any())
            {
                var tryCatchBlock = new AstTryCatchBlock(null);

                // Find the first and widest scope
                var tryStart = ehs.Min(eh => eh.TryStart.Offset);
                var tryEnd = ehs.Where(eh => eh.TryStart.Offset == tryStart).Max(eh => eh.TryEnd.Offset);
                var handlers = ehs.Where(eh => eh.TryStart.Offset == tryStart && eh.TryEnd.Offset == tryEnd).OrderBy(eh => eh.TryStart.Offset).ToList();

                // Remember that any part of the body migt have been removed due to unreachability

                // Cut all instructions up to the try block
                {
                    var tryStartIdx = 0;
                    while (tryStartIdx < body.Count && body[tryStartIdx].Offset < tryStart) tryStartIdx++;
                    ast.AddRange(ConvertToAst(CollectionExtensions.CutRange(body, 0, tryStartIdx)));
                }

                // Cut the try block
                {
                    var nestedEHs = new HashSet<ExceptionHandler>(
                        ehs.Where(eh => (tryStart <= eh.TryStart.Offset && eh.TryEnd.Offset < tryEnd) || (tryStart < eh.TryStart.Offset && eh.TryEnd.Offset <= tryEnd)));
                    ehs.ExceptWith(nestedEHs);
                    var tryEndIdx = 0;
                    while (tryEndIdx < body.Count && body[tryEndIdx].Offset < tryEnd) tryEndIdx++;
                    var converted = ConvertToAst(CollectionExtensions.CutRange(body, 0, tryEndIdx), nestedEHs);
                    tryCatchBlock.TryBlock = new AstBlock(converted.Select(x => x.SourceLocation).FirstOrDefault(), converted);
                }

                // Cut all handlers
                tryCatchBlock.CatchBlocks.Clear();
                foreach (var eh in handlers)
                {
                    var handlerEndOffset = eh.HandlerEnd == null ? methodDef.Body.CodeSize : eh.HandlerEnd.Offset;
                    var startIdx = 0;
                    while (startIdx < body.Count && body[startIdx].Offset < eh.HandlerStart.Offset) startIdx++;
                    var endIdx = 0;
                    while (endIdx < body.Count && body[endIdx].Offset < handlerEndOffset) endIdx++;
                    var nestedEHs = new HashSet<ExceptionHandler>(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < handlerEndOffset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= handlerEndOffset)));
                    ehs.ExceptWith(nestedEHs);
                    var handlerAst = ConvertToAst(CollectionExtensions.CutRange(body, startIdx, endIdx - startIdx), nestedEHs);
                    if (eh.HandlerType == ExceptionHandlerType.Catch)
                    {
                        var catchType = eh.CatchType.IsSystemObject() ? module.TypeSystem.Exception : XBuilder.AsTypeReference(module, eh.CatchType);
                        var catchBlock = new AstTryCatchBlock.CatchBlock(handlerAst.Select(x => x.SourceLocation).FirstOrDefault(), tryCatchBlock)
                        {
                            ExceptionType = catchType,
                            Body = handlerAst
                        };
                        // Handle the automatically pushed exception on the stack
                        var ldexception = ldexceptions[eh];
                        if (ldexception.StoreTo == null || ldexception.StoreTo.Count == 0)
                        {
                            // Exception is not used
                            catchBlock.ExceptionVariable = null;
                        }
                        else if (ldexception.StoreTo.Count == 1)
                        {
                            var first = catchBlock.Body[0] as AstExpression;
                            if (first != null &&
                                first.Code == AstCode.Pop &&
                                first.Arguments[0].Code == AstCode.Ldloc &&
                                first.Arguments[0].Operand == ldexception.StoreTo[0])
                            {
                                // The exception is just poped - optimize it all away;
                                if (context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks)
                                    catchBlock.ExceptionVariable = new AstGeneratedVariable("ex_" + eh.HandlerStart.Offset.ToString("X2"), null);
                                else
                                    catchBlock.ExceptionVariable = null;
                                catchBlock.Body.RemoveAt(0);
                            }
                            else
                            {
                                catchBlock.ExceptionVariable = ldexception.StoreTo[0];
                            }
                        }
                        else
                        {
                            var exTemp = new AstGeneratedVariable("ex_" + eh.HandlerStart.Offset.ToString("X2"), null);
                            catchBlock.ExceptionVariable = exTemp;
                            foreach (var storeTo in ldexception.StoreTo)
                            {
                                catchBlock.Body.Insert(0, new AstExpression(catchBlock.SourceLocation, AstCode.Stloc, storeTo, new AstExpression(catchBlock.SourceLocation, AstCode.Ldloc, exTemp)));
                            }
                        }
                        tryCatchBlock.CatchBlocks.Add(catchBlock);
                    }
                    else if (eh.HandlerType == ExceptionHandlerType.Finally)
                    {
                        tryCatchBlock.FinallyBlock = new AstBlock(handlerAst);
                    }
                    else if (eh.HandlerType == ExceptionHandlerType.Fault)
                    {
                        tryCatchBlock.FaultBlock = new AstBlock(handlerAst);
                    }
                    else
                    {
                        // TODO: ExceptionHandlerType.Filter
                    }
                }

                ehs.ExceptWith(handlers);

                ast.Add(tryCatchBlock);
            }

            // Add whatever is left
            ast.AddRange(ConvertToAst(body));

            return ast;
        }
Esempio n. 38
0
 protected override void OnKeyUp(KeyEventArgs e)
 {
     pressedKeys.Remove(e.KeyCode);
     Game.KeyPressed = pressedKeys.Any() ? pressedKeys.Min() : Keys.None;
 }
Esempio n. 39
0
    // A*
    // http://en.wikipedia.org/wiki/A*_search_algorithm
    // http://wiki.gamegardens.com/Path_Finding_Tutorial
    /// <summary>
    /// A* uses a best-first search and finds the least-cost path from a given initial node to one goal node (out of one or more possible goals).
    /// </summary>
    /// <param name="grid"></param>
    /// <param name="start"></param>
    /// <param name="goal"></param>
    /// <param name="neighbors"></param>
    /// <returns></returns>
    public static IEnumerable <Coordinate> Astar(this long[,] grid, Coordinate start, Coordinate goal, Func <long[, ], Coordinate, IEnumerable <Coordinate> > neighbors)
    {
        var closedSet = new HashSet <Coordinate>();
        var openSet   = new HashSet <Coordinate> {
            start
        };
        var cameFrom = new Dictionary <Coordinate, Coordinate>();

        var gScore = new long[grid.GetLength(0), grid.GetLength(1)];
        var hScore = new long[grid.GetLength(0), grid.GetLength(1)];
        var fScore = new long[grid.GetLength(0), grid.GetLength(1)];

        gScore[start.Row, start.Col] = 0;
        hScore[start.Row, start.Col] = grid.DistanceEstimate(start, goal);
        fScore[start.Row, start.Col] = hScore[start.Row, start.Col];

        while (openSet.Any())
        {
            var min = openSet.Min(v => fScore[v.Row, v.Col]);
            var u   = openSet.First(v => fScore[v.Row, v.Col] == min);

            if (u.Equals(goal))
            {
                foreach (var p in ReconstitutePath(cameFrom, cameFrom[u]))
                {
                    yield return(p);
                }

                yield return(goal);
            }

            openSet.Remove(u);
            closedSet.Add(u);

            foreach (var neighbor in neighbors(grid, u))
            {
                if (closedSet.Contains(neighbor))
                {
                    continue;
                }

                var tentativeGScore   = gScore[u.Row, u.Col] + grid.DistanceBetween(u, neighbor);
                var tentativeIsBetter = false;

                if (!openSet.Contains(neighbor))
                {
                    openSet.Add(neighbor);
                    tentativeIsBetter = true;
                }
                else if (tentativeGScore < gScore[neighbor.Row, neighbor.Col])
                {
                    tentativeIsBetter = true;
                }

                if (tentativeIsBetter)
                {
                    if (cameFrom.TryGetValue(neighbor, out var value))
                    {
                        value = u;
                    }
                    else
                    {
                        cameFrom.Add(neighbor, u);
                    }

                    gScore[neighbor.Row, neighbor.Col] = tentativeGScore;
                    hScore[neighbor.Row, neighbor.Col] = DistanceEstimate(grid, neighbor, goal);
                    fScore[neighbor.Row, neighbor.Col] = gScore[neighbor.Row, neighbor.Col] + hScore[neighbor.Row, neighbor.Col];
                }
            }
        }
    }
Esempio n. 40
0
        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;
        }
Esempio n. 41
0
        private void ConvertTimeEntriesToBlocks(List <Toggl.TogglTimeEntryView> timeEntries)
        {
            var timeStampsList = new List <(TimeStampType Type, TimeEntryBlock Block)>();
            var blocks         = new List <TimeEntryBlock>();

            //The idea is to place all the starts and ends in sorted order and then assign an offset to each time entry block from the list:
            // - if it's a start time stamp, then pick up the minimum available offset, if none is available assign a new one.
            // - if it's an end time stamp, then release the offset which it occupied.
            foreach (var entry in timeEntries)
            {
                var startTime = Toggl.DateTimeFromUnix(entry.Started);
                var height    = ConvertTimeIntervalToHeight(startTime, Toggl.DateTimeFromUnix(entry.Ended));
                var block     = new TimeEntryBlock()
                {
                    Height          = height < 2 ? 2 : height,
                    VerticalOffset  = ConvertTimeIntervalToHeight(new DateTime(startTime.Year, startTime.Month, startTime.Day), startTime),
                    Color           = entry.Color,
                    Description     = entry.Description,
                    ProjectName     = entry.ProjectLabel,
                    ClientName      = entry.ClientLabel,
                    ShowDescription = true,
                    Started         = entry.Started,
                    Ended           = entry.Ended
                };
                if (entry.Started != entry.Ended)
                {
                    timeStampsList.Add((TimeStampType.Start, block));
                    timeStampsList.Add((TimeStampType.End, block));
                }
                else
                {
                    timeStampsList.Add((TimeStampType.Empty, block));
                }
                blocks.Add(block);
            }
            //There can be a situation that next time entry starts exactly at the same moment, the previous one ended.
            //This situation must not be considered as overlap. So the comparison logic if time stamps are the same:
            // - always place the end time stamps first
            // - prefer empty time stamps to start time stamps
            // (otherwise if we discover a start then an empty, this will be considered as overlap, which we want to avoid)
            timeStampsList.Sort((te1, te2) =>
            {
                var time1 = te1.Type == TimeStampType.End ? te1.Block.Ended : te1.Block.Started;
                var time2 = te2.Type == TimeStampType.End ? te2.Block.Ended : te2.Block.Started;
                var res   = time1.CompareTo(time2);
                if (res == 0)
                {
                    var getPriority = new Func <TimeStampType, int>(t =>
                                                                    t == TimeStampType.End ? 0 : t == TimeStampType.Empty ? 1 : 2);
                    return(getPriority(te1.Type) - getPriority(te2.Type));
                }
                return(res);
            });
            var offsets          = new HashSet <double>();
            var curOffset        = 0;
            var usedNumOfOffsets = 0;

            foreach (var item in timeStampsList)
            {
                if (item.Type == TimeStampType.Start || item.Type == TimeStampType.Empty)
                {
                    if (!offsets.Any())
                    {
                        offsets.Add(curOffset);
                        curOffset += 25;
                    }
                    if (usedNumOfOffsets > 0 || item.Block.Height < 20)
                    {
                        item.Block.ShowDescription = false;
                    }
                    item.Block.HorizontalOffset = offsets.Min();
                    offsets.Remove(offsets.Min());
                    usedNumOfOffsets++;
                }
                if (item.Type == TimeStampType.End || item.Type == TimeStampType.Empty)
                {
                    offsets.Add(item.Block.HorizontalOffset);
                    if (usedNumOfOffsets > 1 || item.Block.Height < 20)
                    {
                        item.Block.ShowDescription = false;
                    }
                    usedNumOfOffsets--;
                }
            }
            TimeEntryBlocks = null;
            TimeEntryBlocks = blocks;

            GenerateGapTimeEntryBlocks(timeEntries);
        }
Esempio n. 42
0
        // Condenses the outage log (i.e., reduces the overlapping outages into single outages)
        private void CondenseLog()
        {
            lock (m_readerWriterLock)
            {
                Dictionary <Outage, HashSet <Outage> > outageOverlaps = new Dictionary <Outage, HashSet <Outage> >();

                // Detect overlapping outages
                foreach (Outage outage in this)
                {
                    Outage a = outage;
                    foreach (Outage overlap in this.Where(b => !ReferenceEquals(a, b) && a.StartTime <= b.EndTime && b.StartTime <= a.EndTime))
                    {
                        outageOverlaps.GetOrAdd(outage, o => new HashSet <Outage>()).Add(overlap);
                    }
                }

                // If there are any overlapping outages, we need to reduce set
                if (outageOverlaps.Count > 0)
                {
                    bool originalPostponeState = m_postponeWriteOperations;

                    try
                    {
                        // In this "fix-up" mode, we delay write subsequent log operations until process is complete
                        m_postponeWriteOperations = true;

                        foreach (KeyValuePair <Outage, HashSet <Outage> > overlap in outageOverlaps)
                        {
                            HashSet <Outage> overlaps = overlap.Value;

                            // Add base outage to overlaps so full minimum and maximum range can be determined
                            overlaps.Add(overlap.Key);

                            Outage combinedOutage = new Outage(overlaps.Min(o => o.StartTime), overlaps.Max(o => o.EndTime));
                            bool   outagesRemoved = false;

                            // Remove each overlapping outage
                            foreach (Outage outage in overlaps)
                            {
                                if (Remove(outage))
                                {
                                    outagesRemoved = true;
                                }
                            }

                            // Add a new combined outage of the complete span, assuming any of the outages were removed (could have already been handled)
                            if (outagesRemoved)
                            {
                                Add(combinedOutage);
                            }
                        }

                        m_totalCondenses++;
                    }
                    finally
                    {
                        m_postponeWriteOperations = originalPostponeState;
                        QueueWriteLog();
                    }
                }
            }
        }
Esempio n. 43
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();
        }
Esempio n. 44
0
        /// <summary>
        /// Analyzes the data to compute Width, Height, DeltaX, DeltaY, Maximum and Minimum values.
        /// </summary>
        /// <param name="path">
        /// Path of XYZ file.
        /// </param>
        private static DataGridDetails LoadDataDetails(string path)
        {
            HashSet <double> longitudes = new HashSet <double>();
            HashSet <double> latitudes  = new HashSet <double>();
            HashSet <double> values     = new HashSet <double>();
            FileStream       fileStream = null;

            try
            {
                fileStream = File.OpenRead(path);
                using (StreamReader stream = new StreamReader(fileStream))
                {
                    fileStream = null;
                    string line = stream.ReadLine();
                    if (!string.IsNullOrEmpty(line))
                    {
                        do
                        {
                            string[] parts     = line.Split('\t');
                            double   longValue = 0;
                            double   latValue  = 0;
                            double   value     = 0;
                            if (!double.TryParse(parts[0], out longValue))
                            {
                                longValue = 0;
                            }

                            if (!double.TryParse(parts[1], out latValue))
                            {
                                latValue = 0;
                            }

                            if (!double.TryParse(parts[2], out value))
                            {
                                value = 0;
                            }

                            longitudes.Add(longValue);
                            latitudes.Add(latValue);
                            values.Add(value);

                            line = stream.ReadLine();
                        }while (!string.IsNullOrEmpty(line));
                    }
                }
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Dispose();
                }
            }

            // Added 1 to use the variable as an array index so that the right size is allotted
            int gridWidth  = longitudes.Count() + 1;
            int gridHeight = latitudes.Count() + 1;

            var    boundary         = new Boundary(longitudes.Min(), latitudes.Min(), longitudes.Max(), latitudes.Max());
            double minimumThreshold = values.Min();
            double maximumThreshold = values.Max();

            return(new DataGridDetails(null, gridWidth, gridHeight, boundary, minimumThreshold, maximumThreshold));
        }
		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;
		}
Esempio n. 46
0
        private static bool isPandigital(string s)
        {
            HashSet <int> t = new HashSet <int>(s.ToCharArray().Select(x => Int32.Parse(x.ToString())));

            return((t.Count == 9) && (t.Min() == 1));
        }
Esempio n. 47
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;
        }
Esempio n. 48
0
        static void Main(string[] args)
        {
            Console.WriteLine("Path: ");
            string pathToFile = Console.ReadLine();

            Console.WriteLine("Weight Mode?(Y/N): ");
            string     answer = Console.ReadLine();
            List <int> input  = new List <int>();
            Dictionary <int, double> weights = new Dictionary <int, double>();

            if (answer.ToUpper() == "Y")
            {
                int size  = -1;
                int enter = 1;
                while (enter > 0)
                {
                    Console.WriteLine("Please enter slice size: ");
                    size = Convert.ToInt32(Console.ReadLine());
                    if (size <= 0)
                    {
                        enter = -1;
                    }
                    if (enter > 0)
                    {
                        Console.WriteLine("weight : ");
                        if (!weights.ContainsKey(size) && enter > 0)
                        {
                            double wg = -1;
                            wg = Convert.ToDouble(Console.ReadLine());
                            if (wg > 0.0)
                            {
                                weights.Add(size, wg);
                                input.Add(size);
                            }
                            else
                            {
                                Console.WriteLine("set default weight 1");
                                weights.Add(size, 1);
                                input.Add(size);
                            }
                        }
                    }
                }
                weightsOn = true;
            }
            else
            {
                Console.WriteLine("Insert heights: ");
                string s = Console.ReadLine();
                input     = s.Split(' ').Select(t => Convert.ToInt32(t)).ToList <int>();
                weightsOn = false;
            }


            HashSet <int> legitSliceHights = new HashSet <int>(input);
            //"C:\\Users\\VladKo\\Downloads\\bunny.obj"
            Bitmap3 bmp = createVoxelizedRepresentation(pathToFile);

            printVoxelizedRepresentation(bmp, "C:\\Users\\VladKo\\Downloads\\inputVox.obj");
            if (test)
            {
                getIntersections(60, 50, bmp).ForEach(Console.WriteLine);
            }
            Tuple <Dictionary <Tuple <int, int>, int>, Dictionary <Tuple <int, int, int, int>, int> > errorAndSum = calcErrorAndSum(bmp, legitSliceHights.Max(), legitSliceHights.Min());
            Dictionary <Tuple <int, int>, Tuple <int, int> > algResults = optDiscreteSlicingAlgo(errorAndSum.Item1, legitSliceHights, bmp.Dimensions.y);
            Tuple <int, int> startPoint = findStartPoint(algResults, bmp.Dimensions.y, legitSliceHights.Max(), legitSliceHights.Min());
            List <int>       path       = getOptSlice(startPoint, algResults, legitSliceHights.Min(), bmp.Dimensions.y, weights); //from top to bottom
            Vector3i         newObjDim  = createVector(bmp.Dimensions.x, path.First() - path.Last(), bmp.Dimensions.z);
            Bitmap3          outputObj  = createNewObjectForPriniting(path, errorAndSum.Item2, newObjDim, bmp);

            printVoxelizedRepresentation(outputObj, "C:\\Users\\VladKo\\Downloads\\outputVox.obj");
        }
Esempio n. 49
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;
            }
        }
Esempio n. 50
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;
        }
Esempio n. 51
0
        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);
        }