public CircuitProject() : base() { // Create all sets this.CreateSets(); // Create foreign keys ProjectData.CreateForeignKeys(this); CollapsedCategoryData.CreateForeignKeys(this); CircuitData.CreateForeignKeys(this); DevicePinData.CreateForeignKeys(this); GateData.CreateForeignKeys(this); LogicalCircuitData.CreateForeignKeys(this); PinData.CreateForeignKeys(this); CircuitProbeData.CreateForeignKeys(this); ConstantData.CreateForeignKeys(this); CircuitButtonData.CreateForeignKeys(this); MemoryData.CreateForeignKeys(this); LedMatrixData.CreateForeignKeys(this); SplitterData.CreateForeignKeys(this); SensorData.CreateForeignKeys(this); SoundData.CreateForeignKeys(this); GraphicsArrayData.CreateForeignKeys(this); CircuitSymbolData.CreateForeignKeys(this); WireData.CreateForeignKeys(this); TextNoteData.CreateForeignKeys(this); this.FreezeShape(); this.Init(); }
// Constructor public GateSet(CircuitProject store) { ITableSnapshot table = store.Table("Gate"); if (table != null) { Debug.Assert(store.IsFrozen, "The store should be frozen"); this.Table = (TableSnapshot <GateData>)table; } else { Debug.Assert(!store.IsFrozen, "In order to create table, the store should not be frozen"); this.Table = GateData.CreateTable(store); } this.InitializeGateSet(); }
// This circuit simulator is an extremely simple implementation private void UpdateValues(object sender, EventArgs e) { if (myDiagram.Model == null) { return; } // Don't record any node Value changes in the UndoManager bool oldundo = myDiagram.Model.SkipsUndoManager; myDiagram.Model.SkipsUndoManager = true; // Finds all starter nodes; one must start at these nodes and navigate through the graph List <Node> nodes = new List <Node>(); foreach (Node n in myDiagram.Nodes) { GateData d = n.Data as GateData; if (d != null && d.GateType == "Input") { nodes.Add(n); } } // Updates the current collection of nodes until that collection is empty // (this occurs when all Nodes have been updated and we are at the end of the Diagram); // stops updating if InvalidOperationException is thrown try { // UpdateCollection will modify the collection to hold the nodes to execute next while (nodes.Count > 0) { UpdateCollection(nodes); } } catch (InvalidOperationException) { } // Once all Parts have been updated, // set their Tag properties to null so they can be updated again foreach (Node n in myDiagram.Nodes) { n.Tag = null; } // restore support for undo/redo myDiagram.Model.SkipsUndoManager = oldundo; }
// handle a mouse-down on an input node: toggle its Value if it's a double-click private void StartNodeDoubleClick(object sender, MouseButtonEventArgs e) { // Only executes logic if you have double-clicked. if (DiagramPanel.IsDoubleClick(e)) { myDiagram.StartTransaction("Toggle"); // When you double-click, toggles value of Input node Node input = Part.FindAncestor <Node>(sender as UIElement); if (input != null) { GateData d = input.Data as GateData; if (d != null && d.GateType == "Input") { d.Value = !d.Value; } } myDiagram.CommitTransaction("Toggle"); } }
// Creates Gate wrapper private Gate CreateItem( // Fields of Gate table Guid GateId // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = GateId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); GateData dataGate = new GateData() { GateId = GateId, }; return(this.Create(this.Table.Insert(ref dataGate), rowIdCircuit)); }
// When updating, we will need to update the links leading out of every given node // and update the collection so that it only contains those nodes // that must likewise be updated next time this method is called. private void UpdateCollection(List <Node> nodes) { List <Node> newnodes = new List <Node>(); foreach (Node n in nodes) { GateData data = n.Data as GateData; // One of the starter nodes might have had its value changed by the user. // So, update the values of the links leading out of it to reflect that change. if (data != null && data.GateType == "Input") { foreach (Link l in n.LinksOutOf) { WireData d = l.Data as WireData; if (d != null) { d.Value = data.Value; } } } foreach (Node node in n.NodesOutOf) { GateData outdata = node.Data as GateData; // ignore nodes already "visited" if (node.Tag == null && outdata != null) { node.Tag = node; // declare "visited" newnodes.Add(node); // Checks that the node has the correct number of inputs int numinto = node.LinksInto.Count(); if ((numinto == 1 && outdata.GateType == "OneInOneOut") || (numinto == 2 && outdata.GateType == "TwoInOneOut") || (numinto == 2 && outdata.GateType == "TwoInOneOutCurved") || (numinto == 1 && outdata.GateType == "Output")) { Link[] linksInto = node.LinksInto.ToArray(); WireData link1 = linksInto[0].Data as WireData; WireData link2 = null; if (numinto > 1) { link2 = linksInto[1].Data as WireData; } switch (outdata.Figure) { // Sets new Value depending on the values of the // links leading into it and the kind of NodeFigure case NodeFigure.OrGate: outdata.Value = link1.Value | link2.Value; break; case NodeFigure.NorGate: outdata.Value = !(link1.Value | link2.Value); break; case NodeFigure.AndGate: outdata.Value = link1.Value & link2.Value; break; case NodeFigure.NandGate: outdata.Value = !(link1.Value & link2.Value); break; case NodeFigure.XorGate: outdata.Value = link1.Value ^ link2.Value; break; case NodeFigure.XnorGate: outdata.Value = !(link1.Value ^ link2.Value); break; case NodeFigure.Inverter: outdata.Value = !link1.Value; break; default: outdata.Value = link1.Value; break; } // Once the value of a Node has been updated, // set the values of the links leading out of it foreach (Link outLink in node.LinksOutOf) { WireData d = outLink.Data as WireData; if (d != null) { d.Value = outdata.Value; } } } else { // If the Node has the incorrect number of inputs, stop updating throw new InvalidOperationException(); } } } } // modify the collection to reflect new nodes that need to be executed nodes.Clear(); nodes.AddRange(newnodes); }