// Copyright Keysight Technologies 2012-2019 // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, you can obtain one at http://mozilla.org/MPL/2.0/. using System; using System.Collections; using System.Collections.Generic; using System.Xml.Serialization; namespace OpenTap { /// /// Represents a specific setting/mode/position of a switch. /// public class SwitchPosition : ViaPoint { /// /// Initializes a new instance of the class. /// public SwitchPosition(Instrument device, string name) { Name = name; Device = device; } } /// /// Base class representing a point through which a connection passes. There is a list of these in . /// These usually represent a state that a connection switch element/instrument can be in. Implementations include and /// public abstract class ViaPoint : IEquatable, IConstResourceProperty { /// /// The name of this state/mode/position in the switch. (Should be unique among objects on the same device/resource). /// public virtual string Name { get; protected set; } /// /// Indicates whether the switch is currently in this position. /// Should be set by the Device implementation. /// [XmlIgnore] public virtual bool IsActive { get; set; } /// /// The device (usually an ) on which this switch position exists. /// [XmlIgnore] public IResource Device { get; set; } /// /// Returns a string describing this switch position (string.Format("{0}.{1}", this.Device.Name, this.Name)). /// public override string ToString() { if (Device != null) return $"{Device.Name}.{Name}"; return Name; } /// /// Serves as the default hash function. /// public override int GetHashCode() { return this.Name.GetHashCode() ^ this.Device.GetHashCode(); } /// /// Determines whether the specified object is equal to the current object. /// public override bool Equals(object obj) { if (obj.GetType().IsSubclassOf(typeof(ViaPoint))) { ViaPoint other = (ViaPoint)obj; return this.Name == other.Name && this.Device == other.Device; } return false; } /// /// Determines whether the specified object is equal to the current object. /// public bool Equals(ViaPoint other) { if (other == null) return false; return this.Name == other.Name && this.Device == other.Device; } } /// /// Represents a specific path through a switch matrix. /// public class SwitchMatrixPath : ViaPoint { /// /// Row in the matrix that describes this path /// public int Row { get; private set; } /// /// Column in the matrix that describes this path /// public int Column { get; private set; } /// /// The name of this switch path. (Note the name uses 1-based indexing to refer to the Row/Column) /// public override string Name { get => $"R{Row+1}\u2194C{Column+1}"; protected set => throw new NotSupportedException(); } /// /// Initializes a new instance of the class. /// public SwitchMatrixPath(Instrument device, int row, int column) { Device = device; Row = row; Column = column; } } /// /// Collecion of s that belong to a switch matrix. /// This is a lazy collection that is only populated with actual when each element is accessed or the /// public class SwitchMatrixPathCollection : IEnumerable { /// /// Enumerator for /// private class SwitchMatrixPathCollectionEnumerator : IEnumerator { SwitchMatrixPathCollection col; int currentRow = -1; // Enumerators are positioned before the first element until the first MoveNext() call. int currentColumn = 0; /// /// Gets the element in the collection at the current position of the enumerator. /// public SwitchMatrixPath Current => col.Get(currentRow, currentColumn); object IEnumerator.Current => Current; /// /// Advances the enumerator to the next element of the collection. /// /// /// true if the enumerator was successfully advanced to the next element; false if /// the enumerator has passed the end of the collection. /// public bool MoveNext() { if (currentRow < col.RowCount-1) { currentRow++; return true; } if (currentColumn < col.ColumnCount-1) { currentColumn++; currentRow = 0; return true; } return false; } /// /// Sets the enumerator to its initial position, which is before the first element /// in the collection. /// public void Reset() { currentRow = -1; currentColumn = 0; } /// /// Has no effect in this implementation. /// public void Dispose() { //nothing to do here } internal SwitchMatrixPathCollectionEnumerator(SwitchMatrixPathCollection collection) { this.col = collection; } } private Dictionary<(int, int), SwitchMatrixPath> paths = new Dictionary<(int, int), SwitchMatrixPath>(); private Instrument device; /// /// Number of row in the switch matrix /// public int RowCount { get; private set; } /// /// Number of columns in the switch matrix /// public int ColumnCount { get; private set; } /// /// Gets the corresponding to a particular row and column in the matrix. /// public SwitchMatrixPath this[int row,int column] { get { return Get(row,column); } } /// /// Creates a new instance of /// /// /// /// public SwitchMatrixPathCollection(Instrument device, int rowCount, int columnCount) { this.device = device; this.RowCount = rowCount; this.ColumnCount = columnCount; } /// /// Returns an enumerator that iterates through the collection. /// public IEnumerator GetEnumerator() { return new SwitchMatrixPathCollectionEnumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return new SwitchMatrixPathCollectionEnumerator(this); } /// /// Gets the corresponding to a particular row and column in the matrix. /// private SwitchMatrixPath Get(int row, int column) { if (row >= RowCount || row < 0) throw new ArgumentOutOfRangeException("row"); if (column >= ColumnCount || column < 0) throw new ArgumentOutOfRangeException("column"); SwitchMatrixPath path; if (paths.TryGetValue((row, column),out path)) { return path; } path = new SwitchMatrixPath(device, row, column); paths.Add((row, column), path); return path; } } ///// ///// Represents a specific row for a setting/mode of a switch matrix. ///// //public class SwitchMatrixRow : ViaPoint //{ // /// // /// Initializes a new instance of the class. // /// // public SwitchMatrixRow(Instrument device, string name) // { // Device = device; // Name = name; // } //} ///// ///// Represents a specific column for a setting/mode of a switch matrix. ///// //public class SwitchMatrixColumn : ViaPoint //{ // /// // /// Initializes a new instance of the class. // /// // public SwitchMatrixColumn(Instrument device, string name) // { // Device = device; // Name = name; // } //} }