|
using System;
using System.Collections.Generic;
namespace DataDriven
{
public class InputSet
{
private readonly List<DataContainer> objects;
protected InputSet()
{
objects = new List<DataContainer>();
}
internal InputSet(int capacity)
{
objects = new List<DataContainer>(capacity);
}
internal List<DataContainer> Objects
{
get { return objects; }
}
internal void AddInput(DataContainer dataContainer)
{
Objects.Add(dataContainer);
}
internal void Clear()
{
Objects.Clear();
}
public ProcessInput<T>[] All<T>()
{
return Objects.FindAll(inp => inp.Data is T)
.ConvertAll(inp => new ProcessInput<T>(inp)).ToArray();
}
public T[] AllData<T>()
{
return Objects.FindAll(inp => inp.Data is T)
.ConvertAll(inp => (T)inp.Data).ToArray();
}
public IEnumerable<ProcessInput> All()
{
foreach (DataContainer o in Objects)
{
yield return new ProcessInput(o);
}
}
internal IEnumerable<DataContainer> AllData()
{
foreach (DataContainer o in Objects)
{
yield return o;
}
}
internal DataContainer FindContainer(object data)
{
return Objects.Find(inp => inp.Data == data);
}
/// <summary>Adds input if needed by requirement and
/// returns true if all requirements are satisfied.</summary>
internal bool WouldNeed(DataContainer newInput, ProcessInputRequirements requirements)
{
IEnumerable<InputRequirement> requirement = requirements.GetRequirementFor(newInput);
var containers = new LinkedList<DataContainer>(Objects);
if (requirement != null)
foreach (InputRequirement inputRequirement in requirement)
{
int count = 0;
for (var node = containers.First; node != null; node = node.Next)
{
if (inputRequirement.IsSatisfiedBy(new ProcessInput(node.Value)))
{
containers.Remove(node);
count++;
}
}
int matches = count;
if (matches < requirements.NumberOfRequiedData(inputRequirement))
return true;
}
return false;
}
public ProcessInput<T> Single<T>()
{
var tInputs = new List<ProcessInput<T>>(All<T>());
if (tInputs.Count == 0)
throw new InvalidOperationException("There is no input of type T.");
return tInputs[0];
}
public T SingleData<T>()
{
var tInputs = All<T>();
if (tInputs.Length == 0)
throw new InvalidOperationException("There is no input of type T.");
return tInputs[0].Data;
}
}
public class ProcessInput
{
internal readonly DataContainer DataContainer;
internal ProcessInput(DataContainer dataContainer)
{
DataContainer = dataContainer;
}
/// <summary>
/// Gets the latest process which worked on data.
/// </summary>
public IDataProcess Source
{
get
{
return DataContainer.Source != null
? DataContainer.Source.Process
: null;
}
}
public object Data
{
get { return DataContainer.Data; }
}
/// <summary>
/// Returns true if the data was processed by a given process.
/// </summary>
public bool HasVisited(IDataProcess process)
{
return DataContainer.Track.Exists(pc => pc.Process == process);
}
/// <summary>
/// Gets all former processes which operated on this data so far.
/// </summary>
public IDataProcess[] GetTrack()
{
IDataProcess[] arr;
lock (DataContainer.Track)
{
arr = new IDataProcess[DataContainer.Track.Count - 1]; // exclude the current process
for (int i = 0; i < DataContainer.Track.Count - 1; i++)
{
arr[i] = DataContainer.Track[i].Process;
}
}
return arr;
}
/// <summary>
/// Gets number of processes which used this input data.
/// </summary>
public int FormerProcessCount
{
get
{
return DataContainer.Track.Count - 1;
}
}
}
public class ProcessInput<T> : ProcessInput
{
internal ProcessInput(DataContainer dataContainer) : base(dataContainer)
{
if (!(dataContainer.Data is T))
throw new ArgumentException("Type parameter does not correspond with a type of data.");
}
public new T Data
{
get { return (T)DataContainer.Data; }
}
}
//public class OutputSet : InputSet, IEnumerable
//{
// private readonly ProcessContainer source;
// private readonly InputSet processInput;
// internal OutputSet() : this(null, null)
// {
// }
// internal OutputSet(ProcessContainer source, InputSet processInput)
// {
// this.source = source;
// this.processInput = processInput;
// }
// public void Add(object obj, SendDataParams param)
// {
// DataContainer container = processInput.Objects.Find(dc => dc.Data == obj);
// if (container != null)
// {
// container.Track.Add(source);
// Add(container);
// }
// else
// Objects.Add(new DataContainer
// {
// Data = obj,
// SendParams = param,
// Source = source,
// });
// }
// public static implicit operator OutputSet(object[] arr)
// {
// var set = new OutputSet();
// set.AddRange(arr);
// return set;
// }
// public void AddRange(IEnumerable objects)
// {
// foreach (object obj in objects)
// Add(obj, new SendDataParams());
// }
// public void Add(object obj)
// {
// Add(obj, new SendDataParams());
// }
// public IEnumerator GetEnumerator()
// {
// return Objects.ConvertAll(dc => dc.Data).GetEnumerator();
// }
//}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
My name is Jacek. Currently, I am a Java/kotlin developer. I like C# and Monthy Python's sense of humour.