Files
2026-04-17 14:55:32 -04:00

887 lines
40 KiB
C#

/*
* DTS.Slice.Control.Event.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using DTS.DASLib.Service;
using DTS.Serialization;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
using DTS.Common.Utilities.Logging;
using DTS.Serialization.StringResources;
namespace DTS.Slice.Control
{
/// <summary>
/// Slice control representation of all information related to a slice event.
/// </summary>
public partial class Event
: Exceptional,
Test.IConvertable
{
/// <summary>
/// Get/set the <see cref="string"/> Id for this event.
/// </summary>
public string Id
{
get => _Id.Value;
set => _Id.Value = value;
}
private readonly Property<string> _Id = new Property<string>("DTS.Slice.Control.Event.Id", null, false);
/// <summary>
/// Get/set the description <see cref="string"/> for this event.
/// </summary>
public string Description
{
get => _Description.Value;
set => _Description.Value = value;
}
private readonly Property<string> _Description = new Property<string>("DTS.Slice.Control.Event.Description", null, false);
/// <summary>
/// The globally unique identification string for this event.
/// </summary>
public Guid Guid
{
get => _Guid.Value;
set => _Guid.Value = value;
}
private readonly Property<Guid> _Guid
= new Property<Guid>(typeof(Event).Namespace + ".Event.Guid", new Guid("00000000-0000-0000-0000-000000000000"), true);
/// <summary>
/// The global Fault Flags for this event.
/// </summary>
public UInt16 FaultFlags
{
get => _FaultFlags.Value;
set => _FaultFlags.Value = value;
}
private readonly Property<UInt16> _FaultFlags
= new Property<UInt16>(typeof(Event).Namespace + ".Event.FaultFlags", 0, true);
/// <summary>
/// Get the date of this object's creation. Expected to be populated with the creation
/// date of the serialization from which this object has been generated.
/// </summary>
public DateTime InceptionDate
{
get => _InceptionDate.Value;
private set => _InceptionDate.Value = value;
}
private readonly Property<DateTime> _InceptionDate
= new Property<DateTime>(
typeof(Event).Namespace + ".Event.InceptionDate",
DateTime.Now,
false
);
/// <summary>
/// Get/set this event's list of <see cref="DTS.Slice.Control.Event.Module"/>s.
/// </summary>
public List<Module> Modules
{
get => _Modules.Value;
set => _Modules.Value = value;
}
private readonly Property<List<Module>> _Modules = new Property<List<Module>>("DTS.Slice.Control.Event.Modules", null, false);
/// <summary>
/// Get/set this event's list of <see cref="DTS.Slice.Control.Event.CalculatedChannelsModule"/>s.
/// </summary>
public List<Module.Channel> CalculatedChannels
{
get => _CalculatedChannels.Value;
set => _CalculatedChannels.Value = value;
}
private readonly Property<List<Module.Channel>> _CalculatedChannels = new Property<List<Module.Channel>>("DTS.Slice.Control.Event.CalculatedChannels", null, false);
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event class.
/// </summary>
public Event()
{
}
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event class.
/// </summary>
///
/// <param name="id">
/// The <see cref="string"/> ID of this event.
/// </param>
///
/// <param name="description">
/// The <see cref="string"/> description of this event.
/// </param>
///
public Event(string id, string description)
{
try
{
Id = id;
Description = description;
}
catch (System.Exception ex)
{
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
ex);
}
}
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event class.
/// </summary>
///
/// <param name="test">
/// The <see cref="DTS.Serialization.Test"/> to initialize this object with.
/// </param>
///
public Event(Test test, Test.ReportErrors reportErrors)
{
try
{
FromDtsSerializationTest(test, reportErrors);
}
catch (System.Exception ex)
{
/*throw new Exception(
string.Format(
DataPROWin7.Properties.Resources.DTS_Slice_Control_Event_ConstructionFailedString, this.GetType().FullName),
ex);*/
throw ex;
}
}
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event class.
/// </summary>
///
/// <param name="id">
/// The <see cref="string"/> ID of this event.
/// </param>
///
/// <param name="description">
/// The <see cref="string"/> description of this event.
/// </param>
///
/// <param name="modules">
/// The list of <see cref="DTS.Slice.Control.Event.Module"/>s associated with this event.
/// </param>
///
public Event(string id, string description, List<Module> modules)
{
try
{
Id = id;
Description = description;
Modules = modules;
}
catch (System.Exception ex)
{
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
ex);
}
}
// xxx Event ID, start sample, stop sample,
// xxx Keep a double hash of DAS->Channel... looks like it would probably bypass the
// module concept since the API just returns based on
// Also need to add thread protection.
// xxx Can we set locks in the property accessors for this stuff? At least for the
// data methods... should the constructor need just an enclosure, or a lambda that
// takes a dictionary lookup...
/// <summary>
/// Get a named-DAS/numbered-module accessor to this Event's modules.
/// </summary>
public DasModuleAccessor DasModules
{
get => _DasModules.Value;
private set => _DasModules.Value = value;
}
private readonly Property<DasModuleAccessor> _DasModules
= new Property<DasModuleAccessor>(
typeof(Event).Namespace + ".Event.DasModules",
new DasModuleAccessor(),
true
);
/// <summary>
/// Get a named-DAS/numbered-channel accessor to this Event's channels.
/// </summary>
public DasChannelAccessor DasChannels
{
get => _DasChannels.Value;
private set => _DasChannels.Value = value;
}
private readonly Property<DasChannelAccessor> _DasChannels
= new Property<DasChannelAccessor>(
typeof(Event).Namespace + ".Event.DasChannels",
new DasChannelAccessor(),
true
);
/// <summary>
/// Get a named-DAS/numbered-module/numbered-channel accessor to this Event's channels.
/// </summary>
public DasModuleChannelAccessor DasModuleChannels
{
get => _DasModuleChannels.Value;
private set => _DasModuleChannels.Value = value;
}
private readonly Property<DasModuleChannelAccessor> _DasModuleChannels
= new Property<DasModuleChannelAccessor>(
typeof(Event).Namespace + ".Event.DasModules",
new DasModuleChannelAccessor(),
true
);
public static bool IsG5(IDASCommunication idas)
{
return idas.SerialNumber.StartsWith("5M");
}
const string Slice6DBModule = "slice6db module";
public static bool IsSlice6DBModule(Module module)
{
if (null != module && null != module.Description && module.Description.ToLower() == Slice6DBModule)
{
return true;
}
return false;
}
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event class.
/// </summary>
///
/// <param name="dases">
/// A <see cref="List"/> of <see cref="IConnectedDevice"/>s that will be used
/// to determine the dimensions of the Event's internal structures.
/// </param>
///
public Event(List<IDASCommunication> dases, EventInfoAggregate info)
{
try
{
if (null == dases)
throw new ArgumentNullException(Strings.DTS_Slice_Control_Event_Event_NullDasListString);
if (0 >= dases.Count)
throw new Exception(Strings.DTS_Slice_Control_Event_Event_EmptyDasListString);
Modules = new List<Module>();
var dasTestInformations = new Dictionary<string, TestInformation>();
var absoluteChannelNumber = 0;
foreach (var das in dases)
{
var eventIndex = info.GetEventIndex(das);
if (null == das.SerialNumber)
throw new UserException("Slice API returned no serial number for passed DAS"); // (connect string: " + ( null != das.DASInfo. das.ConnectString ? das.ConnectString : "<NULL>" ) + ")" );
if (null == das.EventInfo)
throw new UserException("Slice API returned no EventInfo for passed DAS");
if (null == das.EventInfo.Events[eventIndex])
throw new UserException("Slice API returned no configuration data for passed DAS"); // \"" + ( null != das.Comm.SensorSerialNumber ? das.Comm.SensorSerialNumber : "<NULL>" ) + "\"" );
var eventInfo = das.EventInfo.Events[eventIndex];
dasTestInformations.Add(das.SerialNumber, new TestInformation(eventInfo.TestID, eventInfo.Description == null ? "" : eventInfo.Description));
DasModules.Add(das.SerialNumber, new List<Module>());
DasChannels.Add(das.SerialNumber, new List<Module.Channel>());
DasModuleChannels.Add(das.SerialNumber, new ModuleChannelAccessor());
if (null != eventInfo.Modules)
{
foreach (var dasModule in new List<DASModule>(eventInfo.Modules))
{
//Add entries for empty slots in a TDAS rack
while (dasModule.ModuleArrayIndex > DasModules[das.SerialNumber].Count)
{
Module emptyModule;
Modules.Add(emptyModule = new Module(this));
DasModules[das.SerialNumber].Add(emptyModule);
}
Module nextModule;
Modules.Add(nextModule = new Module(this));
DasModules[das.SerialNumber].Add(nextModule);
DasModuleChannels[das.SerialNumber].Add(dasModule.ModuleArrayIndex, new ChannelAccessor());
// I think this can be done for everyone (and is the right thing), but for now make it TDAS PRO Rack specific
if (das is EthernetTDAS)
{
// We want module to be the actual SIM or TOM serial number, not the rack serial number
nextModule.DasSerialNumber = das.DASInfo.Modules[dasModule.ModuleArrayIndex].SerialNumber;
}
else
{
nextModule.DasSerialNumber = das.SerialNumber;
}
// This is an important condition if they module property population that occurs after
// this constructor using the dasModules object is going to line thing up right.
Debug.Assert(DasModules[das.SerialNumber].Count - 1 == dasModule.ModuleArrayIndex);
// Maybe these should be getting populated later on using the SetPropertiesFrom(x) after
// the query download successfully returns...?
nextModule.Description = dasModule.Description;
nextModule.AaFilterRateHz = dasModule.AAFilterRateHz;
nextModule.Number = dasModule.ModuleArrayIndex;
nextModule.NumberOfSamples = dasModule.NumberOfSamples;
nextModule.RequestedPostTriggerSeconds = dasModule.RequestedPostTriggerSeconds;
nextModule.RequestedPreTriggerSeconds = dasModule.RequestedPreTriggerSeconds;
nextModule.PostTriggerSeconds = dasModule.PostTriggerSeconds;
nextModule.PreTriggerSeconds = dasModule.PreTriggerSeconds;
nextModule.RecordingMode = dasModule.RecordingMode;
nextModule.SampleRateHz = dasModule.SampleRateHz;
nextModule.StartRecordSampleNumber = dasModule.StartRecordSampleNumber;
nextModule.BaseSerialNumber = dasModule.OwningDAS.SerialNumber;
nextModule.StartRecordTimestampSec = dasModule.StartRecordTimestampSec;
nextModule.StartRecordTimestampNanoSec = dasModule.StartRecordTimestampNanoSec;
nextModule.TriggerTimestampSec = dasModule.TriggerTimestampSec;
nextModule.TriggerTimestampNanoSec = dasModule.StartRecordTimestampNanoSec;
nextModule.PTPMasterSync = dasModule.PTPMasterSync;
nextModule.TiltSensorAxisXDegreesPre = dasModule.TiltSensorAxisXDegreesPre;
nextModule.TiltSensorAxisYDegreesPre = dasModule.TiltSensorAxisYDegreesPre;
nextModule.TiltSensorAxisZDegreesPre = dasModule.TiltSensorAxisZDegreesPre;
nextModule.TiltSensorAxisXDegreesPost = dasModule.TiltSensorAxisXDegreesPost;
nextModule.TiltSensorAxisYDegreesPost = dasModule.TiltSensorAxisYDegreesPost;
nextModule.TiltSensorAxisZDegreesPost = dasModule.TiltSensorAxisZDegreesPost;
nextModule.TemperatureLocation1Pre = dasModule.TemperatureLocation1Pre;
nextModule.TemperatureLocation2Pre = dasModule.TemperatureLocation2Pre;
nextModule.TemperatureLocation3Pre = dasModule.TemperatureLocation3Pre;
nextModule.TemperatureLocation4Pre = dasModule.TemperatureLocation4Pre;
nextModule.TemperatureLocation1Post = dasModule.TemperatureLocation1Post;
nextModule.TemperatureLocation2Post = dasModule.TemperatureLocation2Post;
nextModule.TemperatureLocation3Post = dasModule.TemperatureLocation3Post;
nextModule.TemperatureLocation4Post = dasModule.TemperatureLocation4Post;
nextModule.Channels = new List<Module.Channel>();
var moduleType = dasModule.GetType();
if ((null != dasModule.Channels) && (dasModule.Channels.Length > 0) &&
((dasModule.Channels[0].ConfigurationMode != DASChannel.ConfigMode.DummyArm)|| IsG5(das))
)
{
foreach (var dasChannel in new List<DASChannel>(dasModule.Channels))
{
Module.Channel nextChannel;
nextModule.Channels.Add(nextChannel = Module.Channel.CreateChannel(dasChannel, nextModule, absoluteChannelNumber++));
DasModuleChannels[das.SerialNumber][dasModule.ModuleArrayIndex].Add(dasChannel.ModuleChannelNumber, nextChannel);
nextChannel.Number = dasChannel.ModuleChannelNumber;
nextChannel.Start = dasChannel.EventStartTime;
//Debug.Assert( das.SensorSerialNumber.Equals( dasModule.OwningDAS.SensorSerialNumber, StringComparison.OrdinalIgnoreCase ) );
//if ( null == das.Comm.ChannelDiagnosticsResults )
// throw new DTS.Slice.Control.Event.Exception( "no diagnostics results were received from the API for module " + nextModule.Number.ToString( ) + ", channel " + nextChannel.Number.ToString( ) );
//else
{
nextChannel.UnfilteredData = new List<short>();
DasChannels[das.SerialNumber].Add(nextChannel);
}
}
}
}
}
}
string testId = null;
string testDescription = null;
foreach (var dasId in dasTestInformations.Keys)
{ //
// Walk through the list and verify that all of the test ID and description
// strings are the same.
//
var newTestId = dasTestInformations[dasId].Id;
if (null != testId && !testId.Equals(newTestId, StringComparison.OrdinalIgnoreCase))
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Event_Event_DASTestIdMismatchString, testId, dasId, newTestId));
testId = newTestId;
var newTestDescription = dasTestInformations[dasId].Description;
if (null != testDescription
&& !testDescription.Equals(newTestDescription, StringComparison.OrdinalIgnoreCase))
{
/*throw new Exception(
string.Format(
Properties.Resources.DTS_Slice_Control_Event_Event_DASTestDescriptionMismatchString, testDescription, dasId, newTestDescription));*/
}
else { testDescription = newTestDescription; }
}
if (null == testId) { testId = "Empty"; }
if (null == testDescription) { testDescription = ""; }
if (null == testId || null == testDescription)
throw new Exception(Strings.DTS_Slice_Control_Event_Event_FailedToDetermineIdOrDescriptionFromConfigurationString);
Id = testId;
Description = testDescription;
}
catch (System.Exception ex)
{
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
ex);
}
}
private bool IsTom(DASModule module)
{
try
{
if (module.SerialNumber().ToLower().Contains("tom"))
{
return true;
}
if (null != module.Channels && module.Channels.Length > 0)
{
if (module.Channels[0] is OutputSquibChannel) { return true; }
}
}
catch (System.Exception ex) { APILogger.Log("problem getting serial number", ex); }
return false;
}
/// <summary>
/// Get the highest <see cref="int"/> absolute channel number currently in this event.
/// </summary>
public int LastAbsoluteChannelNumberInEvent
{
get
{
try
{
var highestAbsoluteChannelNumberFound = -1;
foreach (var module in Modules)
foreach (var channel in module.Channels)
if (channel.AbsoluteNumber > highestAbsoluteChannelNumberFound)
highestAbsoluteChannelNumberFound = channel.AbsoluteNumber;
//if ( highestAbsoluteChannelNumberFound < 0 )
// throw new Event.Exception( "no absolute channel numbers exist within this event" );
return highestAbsoluteChannelNumberFound;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting last absolute channel number in event", ex);
}
}
}
/// <summary>
/// Get the <see cref="double"/> per-sample threshold that when exceeded by the total basic data
/// volume of this event results in Event.IsTooLargeFor32BitVisualization to return true.
/// </summary>
///
/// <remarks>
/// Justification for the current default value:
/// With filter caching disabled, the memory usage is AT LEAST 76.4 bytes/sample, broken down thus:
///
/// Event structure:
/// 1 sample needs 2 bytes ADC representation,
/// 8 bytes mV representation,
/// 8 bytes EU representation. Total: 18 bytes
/// +
/// Filtering procedure: 1 sample needs 8 bytes for initial double-sized "ToArray",
/// and 1.1 * ( 8 * 3 ) bytes for the three 5% padded front & end processing arrays
/// inside the algorithm. Total: 34.4 bytes
/// +
/// Viewer memory: 1 sample needs 8 bytes for the internal viewer representation
/// (at a minimum) + ( 2 * 8 ) bytes for the two arrays required to feed the viewer
/// interface. Total: 24 bytes
///
/// = 76.5 bytes/sample.
///
/// Not sure how much memory the rest of SliceWARE takes when up and running, but using this number
/// we seem to be okay if we stay below 1GB, but run into trouble when we go over if we first do other
/// things that might leave things around in memory, i.e., download. The three sections above pretty
/// much stack while loading a test into the viewer.
/// </remarks>
///
private static readonly double MaximumVisualizationBytesPerSample = 2D;
public double TooLargeFor32BitVisualizationBytesPerSampleThreshold
{
get => _TooLargeFor32BitVisualizationBytesPerSampleThreshold.Value;
private set => _TooLargeFor32BitVisualizationBytesPerSampleThreshold.Value = value;
}
private readonly Property<double> _TooLargeFor32BitVisualizationBytesPerSampleThreshold
= new Property<double>(
typeof(Event).FullName + ".TooLargeFor32BitVisualizationBytesPerSampleThreshold",
MaximumVisualizationBytesPerSample,
true
);
/// <summary>
/// Get <see cref="bool"/> value indicating whether or not this event has more combined data than a 32 bit
/// system could handle all at once.
/// </summary>
public bool IsTooLargeFor32BitVisualization
{
get
{
try
{
ulong totalChannelDataCount = 0;
foreach (var module in Modules)
foreach (var channel in module.Channels)
{
if (channel.UnfilteredData is Serialization.TDAS.File.PersistentChannel)
{
totalChannelDataCount += (channel.UnfilteredData as Serialization.TDAS.File.PersistentChannel).NumberOfSamples;
}
else
{
totalChannelDataCount += (channel.UnfilteredData as Serialization.SliceRaw.File.PersistentChannel).NumberOfSamples;
}
}
return (totalChannelDataCount * TooLargeFor32BitVisualizationBytesPerSampleThreshold) > 0x7FFFFFFF;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem determining whether or not this event's combined data is too big for 32-bit visualization", ex);
}
}
}
/// <summary>
/// Get <see cref="bool"/> value indicating whether or not this event contains channels with average over
/// time zero methods, but have specified an invalid averaging window.
/// </summary>
public bool ContainsChannelsActiveInvalidZeroingWindows => ChannelsWithActiveInvalidZeroingWindows.Count > 0;
/// <summary>
/// we initialize the window average to short min value, which is a valid data value but probably means bad things
/// if your window average is legitimately short min value ...
/// </summary>
private const short InvalidWindowAverage = short.MinValue;
/// <summary>
/// Get the list of all <see cref="DTS.Slice.Control.Event.Module.Channel"/>s that with average over time
/// zero method set, but have specified an invalid averaging window.
/// </summary>
public List<Module.Channel> ChannelsWithActiveInvalidZeroingWindows
{
get
{
try
{
var invalidZeroWindowChannels = new List<Module.Channel>();
foreach (var module in Modules)
foreach (var channel in module.Channels)
if (channel is Module.AnalogInputChannel)
{
var analogChannel = channel as Module.AnalogInputChannel;
if (Common.DAS.Concepts.Test.Module.Channel.Sensor.ZeroMethodType.AverageOverTime == analogChannel.ZeroMethod)
{
//if we have a stored window average for the channel, well then it's definitely not an invalid window average ...
if (analogChannel.WindowAverageADC != InvalidWindowAverage) { continue; }
//otherwise check to see if we have an invalid window average
var windowStart = ((analogChannel.ParentModule.TriggerSampleNumbers.Count > 0) ? (double)analogChannel.ParentModule.TriggerSampleNumbers[0] : 0) + (analogChannel.ZeroAverageWindow.Begin * (double)analogChannel.ParentModule.SampleRateHz);
var windowEnd = ((analogChannel.ParentModule.TriggerSampleNumbers.Count > 0) ? (double)analogChannel.ParentModule.TriggerSampleNumbers[0] : 0) + (analogChannel.ZeroAverageWindow.End * (double)analogChannel.ParentModule.SampleRateHz);
if (0 > windowStart || 0 > windowEnd) { invalidZeroWindowChannels.Add(analogChannel); }
else
{
var dataStart = analogChannel.ParentModule.StartRecordSampleNumber;
var dataEnd = dataStart + analogChannel.ParentModule.NumberOfSamples;
if (dataStart > windowStart || windowStart > dataEnd) { invalidZeroWindowChannels.Add(analogChannel); }
else if (dataEnd < windowEnd || windowEnd < dataStart) { invalidZeroWindowChannels.Add(analogChannel); }
}
}
}
return invalidZeroWindowChannels;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem building list of event channels with active invalid zeroing windows", ex);
}
}
}
private bool IsEmptyModule(Module module)
{
foreach (var channel in module.Channels)
{
if (channel.IsConfigured || !IsDummyChannel(channel)) { return false; }
}
return true;
}
private void PurgeUnconfiguredChannels()
{
foreach (var module in Modules)
{
module.Channels.RemoveAll(channel => !channel.IsConfigured || IsDummyChannel(channel));
}
}
/// <summary>
/// Convert this object to a DTS.Serialization.Test.
/// </summary>
///
/// <returns>
/// A <see cref="DTS.Serialization.Test"/> equivalent to this object.
/// </returns>
///
public Test ToDtsSerializationTest()
{
try
{ //
// Create a test to embody the conversion and copy over all relevant
// test data members.
//
var that = new Test();
PurgeUnconfiguredChannels();
that.Id = Id;
that.Description = Description;
that.Guid = Guid;
that.FaultFlags = FaultFlags;
that.Modules = new List<Test.Module>();
foreach (var thisModule in Modules)
{
//Normally, we don't care about empty modules (no data channels), but if it's
//a SLICE6 Distributor (a null ParentEvent), we want to output a module element to the .dts file.
if (IsEmptyModule(thisModule) && !IsSlice6DBModule(thisModule)) { continue; }
//
// Create a test module to embody each module conversion, and then copy
// over all relevant module data members.
//
that.Modules.Add(thisModule.ToDtsSerializationTestModule(that));
}
return that;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem converting " + GetType().FullName + " to " + typeof(Test).FullName, ex);
}
}
/// <summary>
/// Initialize this object from a DTS.Serialization.Test.
/// </summary>
///
/// <param name="that">
/// A <see cref="DTS.Serialization.Test"/> from which to initialize this object.
/// </param>
///
public void FromDtsSerializationTest(Test that, Test.ReportErrors reportErrors)
{
try
{
if (null == that)
throw new ArgumentNullException("cannot set this object's properties from null serialization test reference");
//
// Create the Slice Control test that will be equivalent to the specified serialization
// test and populate its relevant properties.
//
Id = that.Id;
Description = that.Description;
FaultFlags = that.FaultFlags;
Guid = that.Guid;
InceptionDate = that.InceptionDate;
Modules = new List<Module>();
foreach (var thatModule in that.Modules)
{ //
// Create a Slice Control module corresponding to the specified serialization module
// and populate its relevant properties.
//
Modules.Add(new Module(thatModule, this, reportErrors));
}
}
catch (System.IO.InvalidDataException) { throw; }
catch (System.Exception ex)
{
throw new Exception("encountered problem initializing " + GetType().FullName + " using " + typeof(Test).FullName, ex);
}
}
/// <summary>
/// Method to convert a DTS.Slice.Control.Event object to an equivalent DTS.Serialization.Test object.
/// </summary>
///
/// <param name="sliceControlEvent">
/// The <see cref="DTS.Slice.Control.Event"/> to be converted.
/// </param>
///
/// <returns>
/// A <see cref="DTS.Serialization.Test"/> that is equivalent to the specified Slice Control event.
/// </returns>
///
public static implicit operator Test(Event sliceControlEvent)
{
try
{
return sliceControlEvent.ToDtsSerializationTest();
}
catch (System.Exception ex)
{
throw new Exception("encountered problem implicitly converting " + typeof(Event).FullName + " to " + typeof(Test).FullName, ex);
}
}
/// <summary>
/// this really belongs in the channel object, but for now just abstract the function out of
/// where the logic is needed
/// </summary>
/// <param name="channel"></param>
/// <returns></returns>
private bool IsDummyChannel(Module.Channel channel)
{
if (null != channel && channel.ChannelDescriptionString.ToLower() == "dummy arm channel")
{
return true;
}
return false;
}
/// <summary>
/// Get/set the base serialization directory path <see cref="string"/> for events.
/// </summary>
public static string BaseSerializationDirectory
{
get => _BaseSerializationDirectory.Value;
set => _BaseSerializationDirectory.Value = value;
}
private static readonly Property<string> _BaseSerializationDirectory
= new Property<string>(
typeof(Event).Namespace + ".BaseSerializationDirectory",
null,
false
);
/// <summary>
/// Construct the serialization path for the specified event ID.
/// </summary>
///
/// <param name="eventId">
/// The <see cref="string"/> ID of the event whose serialization path is sought.
/// </param>
///
/// <returns>
/// The <see cref="string"/> path for the specified event's serialization.
/// </returns>
///
public static string GetEventSerializationDirectory(string eventId)
{
try
{
return System.IO.Path.Combine(BaseSerializationDirectory, eventId);
}
catch (System.Exception ex)
{
//throw new ReviewForm.Exception("encountered problem getting target directory for test " + (null != eventId ? "\"" + eventId + "\"" : "<NULL>"), ex);
throw new Exception("encountered problem getting target directory for test " + (null != eventId ? "\"" + eventId + "\"" : "<NULL>"), ex);
}
}
/// <summary>
/// Test the specified object for equality with this object.
/// </summary>
///
/// <param name="obj">
/// The <see cref="object"/> to be tested for equality.
/// </param>
///
/// <returns>
/// <see cref="bool"/> true if the specified object has memberwise equality with
/// this object; false otherwise.
/// </returns>
///
public override bool Equals(object obj)
{
try
{
var that = obj as Event;
return null != that
&& Id.Equals(that.Id)
&& Description.Equals(that.Description)
&& Guid.Equals(that.Guid)
&& ModulesEquals(that.Modules)
&& FaultFlags.Equals(that.FaultFlags);
}
catch (System.Exception ex)
{
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Equals_ComparisonFailedString, null != obj ? "\"" + obj.ToString() + "\"" : Strings.DTS_Slice_Control_NullIndicatorString),
ex);
}
}
/// <summary>
/// Test the specified object's module list for equality with this object's
/// module list.
/// </summary>
///
/// <param name="thoseModules">
/// The <see cref="List"/> of <see cref="DTS.Slice.Control.Event.Module"/> objects to be
/// compared for equality with this test's equivalent.
/// </param>
///
/// <returns>
/// <see cref="bool"/> true if the two lists contain equivalent-valued members;
/// false otherwise.
/// </returns>
///
private bool ModulesEquals(List<Module> thoseModules)
{
try
{
if (Modules.Count != thoseModules.Count)
return false;
for (var i = 0; i < thoseModules.Count; i++)
if (!Modules[i].Equals(thoseModules[i]))
return false;
return true;
}
catch (System.Exception ex)
{
throw new Exception(Strings.DTS_Slice_Control_Event_ModuleEquals_ComparisonFailedString, ex);
}
}
/// <summary>
/// Return the hash code for this object.
/// </summary>
///
/// <returns>
/// The <see cref="int"/> hash code for this object.
/// </returns>
///
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}