-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSignalProcessor.cs
More file actions
183 lines (169 loc) · 7.8 KB
/
SignalProcessor.cs
File metadata and controls
183 lines (169 loc) · 7.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================
using RapidField.SolidInstruments.Core.ArgumentValidation;
using System;
using System.Diagnostics;
namespace RapidField.SolidInstruments.SignalProcessing
{
/// <summary>
/// Converts one or more input signals to a single output signal.
/// </summary>
/// <remarks>
/// <see cref="SignalProcessor{TOutput, TSettings, TInputChannels}" /> is the default implementation of
/// <see cref="ISignalProcessor{TOutput, TSettings}" />.
/// </remarks>
/// <typeparam name="TOutput">
/// The type of the signal processor's output value.
/// </typeparam>
/// <typeparam name="TSettings">
/// The type of the operational settings for the signal processor.
/// </typeparam>
/// <typeparam name="TInputChannels">
/// The type of the channel input collection for the signal processor.
/// </typeparam>
public abstract class SignalProcessor<TOutput, TSettings, TInputChannels> : Channel<TOutput>, ISignalProcessor<TOutput, TSettings>
where TSettings : SignalProcessorSettings, new()
where TInputChannels : class, IChannelCollection
{
/// <summary>
/// Initializes a new instance of the <see cref="SignalProcessor{TOutput, TSettings, TInputChannels}" /> class.
/// </summary>
/// <param name="inputChannels">
/// The input channels for the signal processor.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="inputChannels" /> is <see langword="null" />.
/// </exception>
protected SignalProcessor(TInputChannels inputChannels)
: this(inputChannels, new TSettings())
{
return;
}
/// <summary>
/// Initializes a new instance of the <see cref="SignalProcessor{TOutput, TSettings, TInputChannels}" /> class.
/// </summary>
/// <param name="inputChannels">
/// The input channels for the signal processor.
/// </param>
/// <param name="settings">
/// The operational settings for the signal processor.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="inputChannels" /> is <see langword="null" /> -or- <paramref name="settings" /> is
/// <see langword="null" />.
/// </exception>
protected SignalProcessor(TInputChannels inputChannels, TSettings settings)
: this(inputChannels, settings, null)
{
return;
}
/// <summary>
/// Initializes a new instance of the <see cref="SignalProcessor{TOutput, TSettings, TInputChannels}" /> class.
/// </summary>
/// <param name="inputChannels">
/// The input channels for the signal processor.
/// </param>
/// <param name="settings">
/// The operational settings for the signal processor.
/// </param>
/// <param name="name">
/// The name of the signal processor, or <see langword="null" /> to use the name of the signal processor type. The default
/// value is <see langword="null" />.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="inputChannels" /> is <see langword="null" /> -or- <paramref name="settings" /> is
/// <see langword="null" />.
/// </exception>
protected SignalProcessor(TInputChannels inputChannels, TSettings settings, String name)
: base(name)
{
InputChannelsReference = inputChannels.RejectIf().IsNull(nameof(inputChannels));
Settings = settings.RejectIf().IsNull(nameof(settings));
}
/// <summary>
/// Releases all resources consumed by the current <see cref="Channel{T}" />.
/// </summary>
/// <param name="disposing">
/// A value indicating whether or not managed resources should be released.
/// </param>
protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
/// <summary>
/// Attempts to read a discrete unit of output from the channel's output stream at the specified index.
/// </summary>
/// <param name="inputChannels">
/// The processor's input channels.
/// </param>
/// <param name="settings">
/// The processor's operational settings.
/// </param>
/// <param name="index">
/// A zero-based index within the output stream at which to read.
/// </param>
/// <param name="outputValue">
/// The resulting discrete unit of output.
/// </param>
/// <returns>
/// <see langword="true" /> if the read operation was performed, otherwise <see langword="false" />.
/// </returns>
protected abstract Boolean TryRead(TInputChannels inputChannels, TSettings settings, Int32 index, out TOutput outputValue);
/// <summary>
/// Attempts to read a discrete unit of output from the channel's output stream at the specified index.
/// </summary>
/// <param name="index">
/// A zero-based index within the output stream at which to read.
/// </param>
/// <param name="outputValue">
/// The resulting discrete unit of output.
/// </param>
/// <returns>
/// <see langword="true" /> if the read operation was performed, otherwise <see langword="false" />.
/// </returns>
protected sealed override Boolean TryRead(Int32 index, out TOutput outputValue) => TryRead(InputChannelsReference, Settings, index, out outputValue);
/// <summary>
/// Attempts to read a range of discrete units of output from the channel's output stream at the specified index.
/// </summary>
/// <param name="startIndex">
/// A zero-based index within the output stream at which to being reading.
/// </param>
/// <param name="count">
/// The number of output values to read.
/// </param>
/// <param name="outputRange">
/// An array into which the output range should be filled or copied.
/// </param>
/// <returns>
/// <see langword="true" /> if the read operation was performed, otherwise <see langword="false" />.
/// </returns>
protected sealed override Boolean TryRead(Int32 startIndex, Int32 count, TOutput[] outputRange)
{
for (var i = 0; i < count; i++)
{
var index = (startIndex + i);
if (TryRead(index, out var outputValue))
{
outputRange[i] = outputValue;
continue;
}
return false;
}
return true;
}
/// <summary>
/// Gets the input channels for the current <see cref="SignalProcessor{TOutput, TSettings, TInputChannels}" />.
/// </summary>
public IChannelCollection InputChannels => InputChannelsReference;
/// <summary>
/// Gets the operational settings for the current <see cref="SignalProcessor{TOutput, TSettings, TInputChannels}" />.
/// </summary>
public TSettings Settings
{
get;
}
/// <summary>
/// Represents the input channels for the current <see cref="SignalProcessor{TOutput, TSettings, TInputChannels}" />.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly TInputChannels InputChannelsReference;
}
}