internal FunctionNode(IGraphController graphController, string assembly, string qualifiedName, string argumentTypes) : base(graphController, NodeType.Function) { this.Text = this.graphController.GetRuntimeStates().GenerateTempVariable(this.nodeId); this.Assembly = assembly; this.QualifiedName = qualifiedName; this.ArgumentTypes = argumentTypes; this.argumentNames = CoreComponent.Instance.GetArgumentNames(this.Assembly, this.QualifiedName, this.ArgumentTypes); this.UpdateReturnTypeAndMemberType(); int lastDot = 0; string className = string.Empty; switch (this.MemberType) { case LibraryItem.MemberType.Constructor: lastDot = qualifiedName.LastIndexOf('.'); if (-1 == lastDot) this.Caption = qualifiedName; else this.Caption = qualifiedName.Substring(0, lastDot); break; case LibraryItem.MemberType.StaticMethod: lastDot = qualifiedName.LastIndexOf('.'); if (-1 == lastDot) this.Caption = qualifiedName; else this.Caption = qualifiedName.Substring(lastDot + 1); break; case LibraryItem.MemberType.InstanceMethod: case LibraryItem.MemberType.InstanceProperty: lastDot = qualifiedName.LastIndexOf('.'); this.Caption = qualifiedName.Substring(lastDot + 1); break; default: this.Caption = qualifiedName; break; } //Input slot this.CreateInputSlotsFromArgumentTypes(this.ArgumentTypes); //Output slot Slot outputSlot = new Slot(graphController, SlotType.Output, this); this.graphController.AddSlot(outputSlot); this.outputSlots.Add(outputSlot.SlotId); this.replicationGuideStrings.Clear(); this.replicationGuides.Clear(); foreach (uint slot in this.inputSlots) { this.replicationGuides.Add(new List<int>()); this.replicationGuideStrings.Add(string.Empty); } this.CheckDots(); }
internal DriverNode(IGraphController graphController, string text) : base(graphController, NodeType.Driver) { this.centerLine = Configurations.DriverNodeCenterLine; this.Caption = this.graphController.GetRuntimeStates().GenerateTempVariable(this.nodeId); this.Text = Configurations.DriverInitialTextValue; Slot outputSlot = new Slot(graphController, SlotType.Output, this); this.graphController.AddSlot(outputSlot); this.outputSlots.Add(outputSlot.SlotId); }
internal PropertyNode(IGraphController graphController, string assembly, string qualifiedName, string argumentTypes) : base(graphController, NodeType.Property) { this.Caption = qualifiedName; string[] splitQualifiedName = qualifiedName.Split('.'); if (null != splitQualifiedName && (splitQualifiedName.Length >= 1)) this.Caption = splitQualifiedName[1]; this.Text = this.graphController.GetRuntimeStates().GenerateTempVariable(this.nodeId); this.Assembly = assembly; this.QualifiedName = qualifiedName; this.ArgumentTypes = argumentTypes; this.ReturnType = string.Empty; this.UpdateReturnTypeAndMemberType(); this.UpdateInputSlot(); //Output slot Slot outputSlot = new Slot(graphController, SlotType.Output, this); this.graphController.AddSlot(outputSlot); this.outputSlots.Add(outputSlot.SlotId); this.CheckDots(); }
public void TestCreate02() { IGraphController graphController = new GraphController(null); IStorage storage = new BinaryStorage(); IVisualNode node = new FunctionNode(graphController, "", "-", "double,double"); ISlot slot1 = new Slot(graphController, SlotType.Input, node); slot1.Serialize(storage); storage.Seek(0, SeekOrigin.Begin); ISlot slot2 = Slot.Create(graphController, storage); Assert.AreEqual(SlotType.Input, slot2.SlotType); Assert.AreEqual(slot1.SlotId, slot2.SlotId); Assert.AreEqual(slot1.Owners[0], slot2.Owners[0]); Assert.AreEqual(slot1.ConnectingSlots, slot2.ConnectingSlots); }
public void TestSerializeNullException() { IGraphController graphController = new GraphController(null); IStorage storage = null; IVisualNode node = new FunctionNode(graphController, "", "-", "double,double"); ISlot slot = new Slot(graphController, SlotType.Input, node); Assert.Throws<ArgumentNullException>(() => { slot.Serialize(storage); }); }
public void TestDeserilaizeOperationException() { IGraphController graphController = new GraphController(null); IStorage storage = new BinaryStorage(); IVisualNode node = new FunctionNode(graphController, "", "-", "double,double"); ISlot slot = new Slot(graphController, SlotType.Input, node); storage.WriteUnsignedInteger(FieldCode.SlotSignature, 21); storage.Seek(0, SeekOrigin.Begin); Assert.Throws<InvalidOperationException>(() => { slot.Deserialize(storage); }); }
internal VisualEdge CreateLinkingEdge(Slot outputSlot, Slot inputSlot) { this.outputSlotId = outputSlot.SlotId; this.inputSlotId = inputSlot.SlotId; var entry = edgeCollection.FirstOrDefault(x => IsAdded(x.Value)); if ((edgeCollection.Count() != 0) && (entry.Value != null)) return null; IdGenerator idGenerator = ((GraphController)graphController).GetIdGenerator(); VisualEdge visualEdge = new VisualEdge(this, outputSlot.SlotId, inputSlot.SlotId, false); Slot.Connect(outputSlot, inputSlot); edgeCollection.Add(visualEdge.EdgeId, visualEdge); visualEdge.Dirty = true; visualEdge.Compose(); //record UndoRedoRecorder urr = graphController.GetUndoRedoRecorder(); List<IVisualEdge> edgesCreated = new List<IVisualEdge>(); edgesCreated.Add(visualEdge); urr.RecordEdgeCreationForUndo(edgesCreated); return visualEdge; }
internal static void Disconnect(Slot start, Slot end) { if (start == null) throw new ArgumentNullException("start"); if (end == null) throw new ArgumentNullException("end"); start.RemoveConnectingSlot(end.slotId); end.RemoveConnectingSlot(start.slotId); }
private List<uint> PreventDumplicatedSlotId(List<uint> slotIds) { List<uint> subSlotIdList = new List<uint>(); for (int i = 0; i < slotIds.Count; i++) { subSlotIdList = slotIds.GetRange(0, i); if (subSlotIdList.Contains(slotIds[i])) { int dumplicateIdIndex = subSlotIdList.IndexOf(slotIds[i]); ISlot slot = new Slot(this.graphController, SlotType.Output, this); this.graphController.AddSlot(slot); slotIds[dumplicateIdIndex] = slot.SlotId; } } return slotIds; }
private void SetInputSlotsAndLines(Dictionary<int, List<VariableLine>> newInputLines) { if (newInputLines == null) throw new ArgumentNullException("newInputLines"); List<string> oldSetVariables = CodeBlockNode.GetReferencedVariables(this.inputLines, true); List<string> newSetVariables = CodeBlockNode.GetReferencedVariables(newInputLines, true); List<string> variablesToBeRemoved = oldSetVariables.Except(newSetVariables).ToList<string>(); List<uint> newInputSlots = new List<uint>(); foreach (string newVariable in newSetVariables) { uint slotId = this.GetExistingInputSlotByName(newVariable); if (slotId == uint.MaxValue) { if (variablesToBeRemoved.Count > 0) //Assign unreferenced slot to new variable { int index = oldSetVariables.IndexOf(variablesToBeRemoved[0]); slotId = this.inputSlots.ElementAt(index); variablesToBeRemoved.RemoveAt(0); } else //Create new slot for new variable if there is no more unreferenced slot { ISlot slot = new Slot(this.graphController, SlotType.Input, this); this.graphController.AddSlot(slot); slotId = slot.SlotId; } } newInputSlots.Add(slotId); } foreach (string variableToBeRemoved in variablesToBeRemoved) //Remove remaining unreferenced slot { int index = oldSetVariables.IndexOf(variableToBeRemoved); uint slotId = this.inputSlots.ElementAt(index); this.graphController.DeleteEdgesConnectTo(slotId); this.graphController.RemoveSlot(slotId); } //Replace old state with new state this.inputSlots = newInputSlots; this.inputLines = newInputLines; }
internal override Point GetSlotPosition(Slot slot) { if (slot == null) throw new ArgumentNullException("slot"); Point slotPosition = this.nodePosition; slotPosition.Offset(0, 1); int slotIndex = this.GetSlotIndex(slot.SlotId); int lineNumber = -1; if (slot.SlotType == SlotType.Input) lineNumber = CodeBlockNode.GetLineNumberFromInputSlotIndex(this.inputLines, slotIndex); else { slotPosition.X += this.Width; lineNumber = CodeBlockNode.GetLineNumberFromOutputSlotIndex(this.outputLines, slotIndex); } slotPosition.Y += Configurations.SlotOffset + Configurations.SlotSize / 2; //slotPosition.Y += lineNumber * Configurations.FontPixels; slotPosition.Y += GetHeightFromLineNumber(lineNumber); return slotPosition; }
private void SetOutputSlotsAndLines(List<VariableLine> newOutputLines) { if (newOutputLines == null) throw new ArgumentNullException("newOutputLines"); // As it goes through and create fresh output slots, the CBN tries // its best to retain existing output connections. However, those // connections can only be preserved, only if the output variables // remain the same names after the change. In other word, this process // is highly specific to names of variables being defined in the new // content. To illustrate this process better, let's consider the // following scenario: // // oldVariables = { a, b, } // oldSlotIds = { 301, 302 } // // newVariables = { b, c, d } // newSlotIds = { 302, ???, ??? } // List<string> newVariables = CodeBlockNode.GetDefinedVariables(newOutputLines, true); // Here we figure out what are the slot IDs the CBN currently has, and // what variable names they map to. This map is important since there can // be more than one slot mapping to the same variable (imagine a variable // is assigned multiple times, each of them will have one output slot, it // is just that we only display the first output slot as of this writing). // // In our scenario, the map would have the following content: // // slotToNameMap = { [301, a], [302, b] } // int i = 0; Dictionary<uint, string> slotToNameMap = new Dictionary<uint, string>(); Dictionary<uint, string> slotsToRemove = new Dictionary<uint, string>(); foreach (VariableLine variableLine in this.outputLines) { slotToNameMap.Add(this.outputSlots[i], variableLine.variable); slotsToRemove.Add(this.outputSlots[i], variableLine.variable); i++; } // Given the old list { a, b } and the new { b, c, d }, we then compute // the delta and figure out which are the old ones we need to remove. In // our example here the dictionary would contain a single element 'a': // // slotsToRemove = { [301, a] } // foreach (string newVariable in newVariables) { // There may be more than one output slot with the same variable name // (e.g. variable redefinition), so we will remove them one at a time. if (slotsToRemove.ContainsValue(newVariable)) { KeyValuePair<uint, string> foundSlot = slotsToRemove.First((x) => (x.Value == newVariable)); slotsToRemove.Remove(foundSlot.Key); // Remove the entry, we still need this variable. } } // New output slots to be generated in this loop. List<uint> newOutputSlots = new List<uint>(); foreach (string newVariable in newVariables) // newSetVariables = { b, c, d } { // See if any of the { b, c, d } has an output slot before (only 'b' should have). // uint slotId = uint.MaxValue; if (slotToNameMap.ContainsValue(newVariable)) { KeyValuePair<uint, string> foundSlot = slotToNameMap.First((x) => (x.Value == newVariable)); slotId = foundSlot.Key; // Found a slot to be reused, for 'b' it is '302'. slotToNameMap.Remove(foundSlot.Key); // Now that's reused, remove it from map. } if (slotId == uint.MaxValue) // Variable does not match to any output slot. { // No slot could be found for 'c', we know we need a new slot ID for it. // But instead of go ahead to create a new slot, we'll see what can be // reused in "slotsToRemove = { [301, a] }" since we are going to remove // it. So here we found 'a', which are going to be removed, but can be // reused, so we reuse its slot ID '301' here. // if (slotsToRemove.Count > 0) { // Here we found 'a' can be reused, so reuse slot ID '301'. KeyValuePair<uint, string> slotToReuse = slotsToRemove.First(); slotsToRemove.Remove(slotToReuse.Key); slotId = slotToReuse.Key; } else { // We will get here for new variable 'd', because after 'a' was // removed above, 'd' will not find any left over for it to take // from "slotsToRemove". In this case, a new slot object needs // to be created for 'd' (which is '304' in our case). // ISlot slot = new Slot(this.graphController, SlotType.Output, this); this.graphController.AddSlot(slot); slotId = slot.SlotId; // Newly created slot object will have new ID. } } newOutputSlots.Add(slotId); // In the end, newOutputSlots = { 302, 301, 304 } } // Say if we were not able to reuse all those old variables (e.g. when // we have less new variables than old variables), then here we remove // them, as well as the edges connecting to them. Of course this includes // updating the content of another slot that is connecting to the slot we // are removing. // foreach (KeyValuePair<uint, string> slotToRemove in slotsToRemove) { this.graphController.DeleteEdgesConnectTo(slotToRemove.Key); this.graphController.RemoveSlot(slotToRemove.Key); } // Replace old state with new state this.outputLines = FilterArrayElementVariable(newOutputLines); this.outputSlots = PreventDumplicatedSlotId(newOutputSlots); EnsureOutputEdgeConnectivity(); }
internal void DeleteImplicitEdge(Slot outputSlot, Slot inputSlot) { this.inputSlotId = inputSlot.SlotId; this.outputSlotId = outputSlot.SlotId; var entry = edgeCollection.FirstOrDefault(x => IsAdded(x.Value)); UndoRedoRecorder urr = graphController.GetUndoRedoRecorder(); List<IVisualEdge> edgesToDelete = new List<IVisualEdge>(); edgesToDelete.Add(entry.Value); urr.RecordEdgeDeletionForUndo(edgesToDelete); DeleteVisualEdge(entry.Value); Slot.Disconnect(outputSlot, inputSlot); }
private void UpdateInputSlot() { LibraryItem libraryItem = CoreComponent.Instance.GetLibraryItem(this.Assembly, this.QualifiedName, this.ArgumentTypes); if (libraryItem.Type == LibraryItem.MemberType.InstanceProperty) { //1 Input slot Slot newSlot = new Slot(graphController, SlotType.Input, this); this.graphController.AddSlot(newSlot); this.inputSlots.Add(newSlot.SlotId); } else if (this.ArgumentTypes.Count() != 0) { Slot newSlot = new Slot(graphController, SlotType.Input, this); this.graphController.AddSlot(newSlot); this.inputSlots.Add(newSlot.SlotId); } }
private void CreateInputSlotsFromArgumentTypes(string argumentTypes) { replicationGuides.Clear(); if (!String.IsNullOrEmpty(argumentTypes)) // If there's any argument being specified. { char[] delimiter = new char[] { ',' }; string[] types = argumentTypes.Split(delimiter, StringSplitOptions.RemoveEmptyEntries); if (null != types && (types.Length > 0)) { foreach (string type in types) { Slot inputSlot = new Slot(graphController, SlotType.Input, this); this.graphController.AddSlot(inputSlot); this.inputSlots.Add(inputSlot.SlotId); replicationGuides.Add(new List<int>()); } this.UpdateReplicationGuideStrings(); } } }
/// <summary> /// Create an instance of a slot given storage /// </summary> /// <param name="graphController"></param> /// <param name="storage"></param> /// <returns></returns> internal static ISlot Create(IGraphController graphController, IStorage storage) { if (graphController == null || storage == null) throw new ArgumentNullException("graphController, storage"); ISlot slot = new Slot(graphController); slot.Deserialize(storage); return slot; }
internal virtual Point GetSlotPosition(Slot slot) { if (slot == null) throw new ArgumentNullException(); if (slot.SlotType == SlotType.Input) { // @TODO(Victor): There's no checking "inputSlots" against "null" or "0". // (Ben): in the GetSlotIndex(), it throws exception when the slot id is invalid return GetInputIndexPosition(GetSlotIndex(slot.SlotId)); } else return GetOutputIndexPosition(); }
internal static bool IsConnected(Slot start, Slot end) { if (start == null) throw new ArgumentNullException("start"); if (end == null) throw new ArgumentNullException("end"); List<uint> startConnectingSlots = new List<uint>(); if (start.ConnectingSlots != null) startConnectingSlots.AddRange(start.ConnectingSlots); List<uint> endConnectingSlots = new List<uint>(); if (end.ConnectingSlots != null) endConnectingSlots.AddRange(end.ConnectingSlots); if (startConnectingSlots.Contains(end.SlotId) && endConnectingSlots.Contains(start.SlotId)) return true; return false; }
private VisualEdge RebuildImplicitEdge(Slot outputSlot, Slot inputSlot) { this.outputSlotId = outputSlot.SlotId; this.inputSlotId = inputSlot.SlotId; var entry = edgeCollection.FirstOrDefault(x => IsAdded(x.Value)); if ((edgeCollection.Count() == 0) || (entry.Value == null)) { IdGenerator idGenerator = ((GraphController)graphController).GetIdGenerator(); VisualEdge visualEdge = new VisualEdge(this, outputSlot.SlotId, inputSlot.SlotId, true); edgeCollection.Add(visualEdge.EdgeId, visualEdge); visualEdge.Dirty = true; visualEdge.Compose(); return visualEdge; } entry.Value.Dirty = true; entry.Value.Compose(); return entry.Value; }