// 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;
// }
//}
}