/// <summary> /// Forms new connections from the external nodes to the Node To Code Node, /// based on the connectors passed as inputs. /// </summary> /// <param name="externalInputConnections">List of connectors to remake, along with the port names of the new port</param> /// <param name="codeBlockNode">The new Node To Code created Code Block Node</param> private void ReConnectInputConnections(Dictionary <ConnectorModel, string> externalInputConnections, CodeBlockNodeModel codeBlockNode) { foreach (var kvp in externalInputConnections) { var connector = kvp.Key; string variableName = kvp.Value; int startIndex = 0, endIndex = 0; //Find the start and end index of the ports for the connection startIndex = connector.Start.Owner.OutPorts.IndexOf(connector.Start); endIndex = CodeBlockNodeModel.GetInportIndex(codeBlockNode, variableName); //For inputs, a single node can be an input to multiple nodes in the code block node selection //After conversion, all these connecetions should become only 1 connection and not many //Hence for inputs, it is required to make sure that a certain type of connection has not //been created already. if (Connectors.Where(x => (x.Start == connector.Start && x.End == codeBlockNode.InPorts[endIndex])).FirstOrDefault() == null) { //Make the new connection and then record and add it var newConnector = ConnectorModel.Make(connector.Start.Owner, codeBlockNode, startIndex, endIndex, PortType.INPUT); this.Connectors.Add(newConnector); UndoRecorder.RecordCreationForUndo(newConnector); } } }
/// <summary> /// Forms new connections from the external nodes to the Node To Code Node, /// based on the connectors passed as inputs. /// </summary> /// <param name="externalOutputConnections">List of connectors to remake, along with the port names of the new port</param> /// <param name="codeBlockNode">The new Node To Code created Code Block Node</param> private void ReConnectOutputConnections(Dictionary <ConnectorModel, string> externalOutputConnections, CodeBlockNodeModel codeBlockNode) { foreach (var kvp in externalOutputConnections) { var connector = kvp.Key; string variableName = kvp.Value; int startIndex = 0, endIndex = 0; //Get the start and end idex for the ports for the connection endIndex = connector.End.Owner.InPorts.IndexOf(connector.End); int i = 0; for (i = 0; i < codeBlockNode.OutPorts.Count; i++) { if (codeBlockNode.GetAstIdentifierForOutputIndex(i).Value == variableName) { break; } } var portModel = codeBlockNode.OutPorts[i]; startIndex = codeBlockNode.OutPorts.IndexOf(portModel); //Make the new connection and then record and add it var newConnector = ConnectorModel.Make(codeBlockNode, connector.End.Owner, startIndex, endIndex, PortType.INPUT); this.Connectors.Add(newConnector); UndoRecorder.RecordCreationForUndo(newConnector); } }
public void Redo(int numberOfRedo = 1) { for (int i = 0; i < numberOfRedo; i++) { if (RedoBuffer.Count == 0) { return; } var last = RedoBuffer.OrderByDescending(kvp => kvp.Key).Last(); RedoBuffer.Remove(last.Key); var level = last.Value.Level; var undoRecorder = new UndoRecorder(level, false); var editSession = new EditHelper(level, undoRecorder: undoRecorder); // Redo var restore = last.Value.Postsnapshot; foreach (Block block in restore) { editSession.SetBlock(block); } var history = undoRecorder.CreateHistory(); AddHistory(history, true); } }
public EditHelper(Level level, Mask mask = null, bool randomizeGeneration = false, UndoRecorder undoRecorder = null) { _level = level; _mask = mask; _randomizeGeneration = randomizeGeneration; _undoRecorder = undoRecorder; }
public override bool Animate(Level world, Player player) { player.Inventory.SendSetSlot(player.Inventory.InHandSlot); var selector = RegionSelector.GetSelector(player); var undoRecorder = new UndoRecorder(player.Level); var editSession = new EditHelper(player.Level, Mask, undoRecorder: undoRecorder); var target = new EditHelper(world).GetBlockInLineOfSight(player.Level, player.KnownPosition, returnLastAir: true); if (target == null) { player.SendMessage("No block in range"); return(false); } try { switch (BrushType) { case 0: editSession.MakeSphere(target.Coordinates, Pattern, Radius, Radius, Radius, Filled); break; case 1: editSession.MakeCylinder(target.Coordinates, Pattern, Radius, Radius, Height, Filled); break; case 3: // public ErosionParameters(final int erosionFaces, final int erosionRecursion, final int fillFaces, final int fillRecursion) { //MELT(new ErosionParameters(2, 1, 5, 1)), //FILL(new ErosionParameters(5, 1, 2, 1)), //SMOOTH(new ErosionParameters(3, 1, 3, 1)), //LIFT(new ErosionParameters(6, 0, 1, 1)), //FLOATCLEAN(new ErosionParameters(6, 1, 6, 1)); Erosion(editSession, Radius, 2, 1, 5, 1, world, target.Coordinates); // melt break; case 2: Erosion(editSession, Radius, 5, 1, 2, 1, world, target.Coordinates); // fill break; } } catch (Exception e) { Log.Error("Brush use item", e); } var history = undoRecorder.CreateHistory(); selector.AddHistory(history); return(true); }
/// <summary> /// This method assumes an undo-redo action group already exists /// and records in it models that are modified. /// </summary> /// <param name="models"></param> internal void RecordModelsForModification(List <ModelBase> models) { if (null == UndoRecorder) { return; } if (!ShouldProceedWithRecording(models)) { return; } foreach (var model in models) { UndoRecorder.RecordModificationForUndo(model); } }
internal void ConvertNodesToCodeInternal(Guid nodeId) { IEnumerable <NodeModel> nodes = DynamoSelection.Instance.Selection.OfType <NodeModel>().Where(n => n.IsConvertible); if (!nodes.Any()) { return; } Dictionary <string, string> variableNameMap; string code = dynSettings.Controller.EngineController.ConvertNodesToCode(nodes, out variableNameMap); //UndoRedo Action Group---------------------------------------------- UndoRecorder.BeginActionGroup(); #region Step I. Delete all nodes and their connections //Create two dictionarys to store the details of the external connections that have to //be recreated after the conversion var externalInputConnections = new Dictionary <ConnectorModel, string>(); var externalOutputConnections = new Dictionary <ConnectorModel, string>(); //Also collect the average X and Y co-ordinates of the different nodes var nodeList = nodes.ToList(); int nodeCount = nodeList.Count; double totalX = 0, totalY = 0; for (int i = 0; i < nodeList.Count; ++i) { var node = nodeList[i]; #region Step I.A. Delete the connections for the node var connectors = node.AllConnectors as IList <ConnectorModel>; if (null == connectors) { connectors = node.AllConnectors.ToList(); } for (int n = 0; n < connectors.Count(); ++n) { var connector = connectors[n]; if (!IsInternalNodeToCodeConnection(connector)) { //If the connector is an external connector, the save its details //for recreation later var startNode = connector.Start.Owner; int index = startNode.OutPorts.IndexOf(connector.Start); //We use the varibleName as the connection between the port of the old Node //to the port of the new node. var variableName = startNode.GetAstIdentifierForOutputIndex(index).Value; if (variableNameMap.ContainsKey(variableName)) { variableName = variableNameMap[variableName]; } //Store the data in the corresponding dictionary if (startNode == node) { externalOutputConnections.Add(connector, variableName); } else { externalInputConnections.Add(connector, variableName); } } //Delete the connector UndoRecorder.RecordDeletionForUndo(connector); connector.NotifyConnectedPortsOfDeletion(); Connectors.Remove(connector); } #endregion #region Step I.B. Delete the node totalX += node.X; totalY += node.Y; UndoRecorder.RecordDeletionForUndo(node); Nodes.Remove(node); #endregion } #endregion #region Step II. Create the new code block node var codeBlockNode = new CodeBlockNodeModel(code, nodeId, this, totalX / nodeCount, totalY / nodeCount); UndoRecorder.RecordCreationForUndo(codeBlockNode); Nodes.Add(codeBlockNode); #endregion #region Step III. Recreate the necessary connections ReConnectInputConnections(externalInputConnections, codeBlockNode); ReConnectOutputConnections(externalOutputConnections, codeBlockNode); #endregion UndoRecorder.EndActionGroup(); //End UndoRedo Action Group------------------------------------------ // select node var placedNode = dynSettings.Controller.DynamoViewModel.Model.Nodes.Find((node) => node.GUID == nodeId); if (placedNode != null) { DynamoSelection.Instance.ClearSelection(); DynamoSelection.Instance.Selection.Add(placedNode); } Modified(); }