/// <summary> /// Cloning Constructor. /// Cloning the whole circuit is pretty difficult somehow! /// </summary> /// <param name="original">original object to create clone from</param> private Circuit(Circuit original) { //create connections to connect the cloned elements to List <Connection> connlist = new List <Connection>(); foreach (BaseElement element in original.m_Elements) { if (element is Connection) { Connection cloned = new Connection(); cloned.Name = element.Name; connlist.Add(cloned); } } //clone elements foreach (BaseElement element in original.m_Elements) { if (element is InputOutputElement) { InputOutputElement io = element as InputOutputElement; InputOutputElement cloned = io.Clone(); ConnectClonedTerminals(io, cloned, connlist); AddElement(cloned); } } // add the connections to the circuit clone foreach (Connection connection in connlist) { if (connection.Terminals.Count > 0) { AddElement(connection); } } }
public override void Logic() { //use matching to deploy states of Terminals to the SignalInputs within circuit foreach (Terminal terminal in Inputs) { InputOutputElement io = m_Matching.FindIOElement(terminal); if (io != null) { terminal.Update(); (io as SignalInput).State = terminal.State; //io.Logic(); } } //run circuit m_Circuit.Update(); //use matching to deploy states of SignalOutputs within circuit to the Terminals for (int index = 0; index < Outputs.Length; index++) { InputOutputElement io = m_Matching.FindIOElement(Outputs[index]); if (io != null) { //io.Logic(); m_PreStates[index] = (io as SignalOutput).State; } } }
/// <summary> /// Adds a new Matching /// </summary> /// <param name="terminal"></param> /// <param name="ioElement"></param> public void AddMatching(Terminal terminal, InputOutputElement ioElement) { if (ioElement is SignalInput == false && ioElement is SignalOutput == false) { throw new ArgumentException("Type of IOElement not supported for matching."); } m_MatchingDict.Add(terminal, ioElement); }
public override void AddElement(BaseElement element) { if (element is InputOutputElement) { InputOutputElement io = (element as InputOutputElement); io.UpdateIndex = m_NextIndex; m_NextIndex++; io.OnUpdateIndexChanged += new DigitalClasses.Events.UpdateIndexChanged(UpdateIndexChangedEventHandler); } base.AddElement(element); SortElements(); }
/// <summary> /// Part of the cloning constructor. /// Connects the cloned terminals to the cloned connections. /// </summary> /// <param name="io">original element object</param> /// <param name="cloned">cloned element object</param> /// <param name="connlist">list with connections</param> private void ConnectClonedTerminals(InputOutputElement io, InputOutputElement cloned, List <Connection> connlist) { //inputs for (int i = 0; i < io.Inputs.Length; i++) { if (io.Inputs[i].IsConnected == false) { continue; } string connectionName = io.Inputs[i].Connection.Name; Connection destConn = connlist.Find( delegate(Connection connection) { if (connection.Name.Equals(connectionName)) { return(true); } return(false); } ); if (destConn != null) { destConn.ConnectTerminal(cloned.Inputs[i]); } } //outputs for (int i = 0; i < io.Outputs.Length; i++) { if (io.Outputs[i].IsConnected == false) { continue; } string connectionName = io.Outputs[i].Connection.Name; Connection destConn = connlist.Find( delegate(Connection connection) { if (connection.Name.Equals(connectionName)) { return(true); } return(false); } ); if (destConn != null) { destConn.ConnectTerminal(cloned.Outputs[i]); } } }
/// <summary> /// Handles index change by user. Those changes may need change in other indices. /// </summary> /// <param name="sender">element whose index was changed</param> /// <param name="e">EventArgs containing further information</param> private void UpdateIndexChangedEventHandler(object sender, UpdateIndexChangedEventArgs e) { if (m_IgnoreEvents) { return; } InputOutputElement senderio = sender as InputOutputElement; #region Old > New if (e.OldIndex > e.NewIndex) { //increase all indices between the new and the old value m_IgnoreEvents = true; foreach (BaseElement be in m_Elements) { if (be is InputOutputElement) { InputOutputElement beio = be as InputOutputElement; if (!beio.Equals(senderio) && beio.UpdateIndex >= e.NewIndex && beio.UpdateIndex < e.OldIndex) { beio.UpdateIndex++; } } } m_IgnoreEvents = false; } #endregion #region New > Old if (e.OldIndex < e.NewIndex) { //decrease all indices between the new and the old value m_IgnoreEvents = true; foreach (BaseElement be in m_Elements) { if (be is InputOutputElement) { InputOutputElement beio = be as InputOutputElement; if (!beio.Equals(senderio) && beio.UpdateIndex > e.OldIndex && beio.UpdateIndex <= e.NewIndex) { beio.UpdateIndex--; } } } m_IgnoreEvents = false; } #endregion SortElements(); }
/// <summary> /// Find corresponding Terminal in reverse direction /// </summary> /// <param name="ioElement">IO to find Terminal for</param> /// <returns>Corresponsing Terminal or null if not found</returns> public Terminal FindTerminal(InputOutputElement ioElement) { InputOutputElement[] ioArray = new InputOutputElement[m_MatchingDict.Values.Count]; m_MatchingDict.Values.CopyTo(ioArray, 0); Terminal[] termArray = new Terminal[m_MatchingDict.Keys.Count]; m_MatchingDict.Keys.CopyTo(termArray, 0); if (m_MatchingDict.ContainsValue(ioElement)) { for (int i = 0; i < m_MatchingDict.Values.Count; i++) { if (ioElement.Equals(ioArray[i])) { return(termArray[i]); } } } return(null); }
/// <summary> /// Updates all InputOutputElements within the circuit. Therefore their logic method will be run. /// </summary> public void Update() { //elements are sorted by type and the UpdateIndex, //when run the logic method is run, the result is stored internally foreach (BaseElement element in m_Elements) { InputOutputElement io = element as InputOutputElement; if (io != null) { io.Logic(); } } //upon propagation the internal result is set to their outputs foreach (BaseElement element in m_Elements) { InputOutputElement io = element as InputOutputElement; if (io != null) { io.Propagate(); } } }
public override bool RemoveElement(BaseElement element) { if (element is InputOutputElement) { InputOutputElement io = (element as InputOutputElement); io.OnUpdateIndexChanged -= UpdateIndexChangedEventHandler; m_IgnoreEvents = true; foreach (BaseElement be in m_Elements) { if (be is InputOutputElement) { InputOutputElement beio = be as InputOutputElement; if (beio.UpdateIndex > io.UpdateIndex) { beio.UpdateIndex--; } } } m_IgnoreEvents = false; } return(base.RemoveElement(element)); }