using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Serialization;
using System.Xml;
using CategoryTheory;
using BaseTypes;
using DiagramUI;
using DiagramUI.Interfaces;
using FormulaEditor;
using DataPerformer.Interfaces;
using DataPerformer.SeriesTypes;
using DataPerformer.Measures;
using DataPerformer.Helpers;
namespace DataPerformer
{
/// <summary>
/// Base class of data consumers
/// </summary>
[Serializable()]
public class DataConsumer : CategoryObject, ISerializable, IDataConsumer
{
#region Fields
private event Action onChangeInput = () => { };
/// <summary>
/// Interrupted excfeption
/// </summary>
public const string Interrupted = "Interrupted";
/// <summary>
/// Error message of variables shortage
/// </summary>
public static readonly string VariablesShortage = "Shortage of variables";
/// <summary>
/// Arrows to data providers
/// </summary>
protected List<IMeasurements> measurementsData;
/// <summary>
/// Type of consumer
/// </summary>
protected int type;
/// <summary>
/// Update flag
/// </summary>
protected bool isUpdated;
/// <summary>
/// Comments
/// </summary>
protected byte[] comments;
/// <summary>
/// Controls of graph
/// </summary>
private ArrayList graphControls = new ArrayList();
/// <summary>
/// Start
/// </summary>
private double start = 0;
/// <summary>
/// Step
/// </summary>
private double step = 1;
/// <summary>
/// Number of steps
/// </summary>
private int steps = 2;
/// <summary>
/// Runtime wrapper
/// </summary>
protected RuntimeWrapper rtw;
#endregion
#region Ctor
/// <summary>
/// Constructor
/// </summary>
/// <param name="type">Type of consumer</param>
public DataConsumer(int type)
{
rtw = new RuntimeWrapper(this);
this.type = type;
initialize();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public DataConsumer(SerializationInfo info, StreamingContext context)
{
rtw = new RuntimeWrapper(this);
type = (int)info.GetValue("Type", typeof(int));
try
{
graphControls = (ArrayList)info.GetValue("GraphConrtols", typeof(ArrayList));
start = (double)info.GetValue("Start", typeof(double));
step = (double)info.GetValue("Step", typeof(double));
steps = (int)info.GetValue("Steps", typeof(int));
}
catch (Exception ex)
{
ex.ShowError(10);
}
initialize();
}
#endregion
#region ISerializable Members
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Type", type);
info.AddValue("GraphConrtols", graphControls);
info.AddValue("Start", start);
info.AddValue("Step", step);
info.AddValue("Steps", steps);
}
#endregion
#region Static Helper Members
/// <summary>
/// Creates document with arrays
/// </summary>
/// <param name="consumer">Data consumer</param>
/// <returns>Xml document</returns>
public static XmlDocument GetArraysXmlDocument(IDataConsumer consumer)
{
ArrayList meas = new ArrayList();
int[] r = null;
int n = consumer.Count;
for (int i = 0; i < n; i++)
{
IMeasurements mea = consumer[i];
int k = mea.Count;
for (int j = 0; j < k; j++)
{
IMeasure m = mea[j];
object type = m.Type;
if (!(type is ArrayReturnType))
{
continue;
}
ArrayReturnType art = type as ArrayReturnType;
int[] rr = art.Dimension;
if (rr.Length > 1)
{
continue;
}
if (r == null)
{
r = rr;
}
if (r[0] != rr[0])
{
continue;
}
meas.Add(m);
}
}
if (r == null)
{
return null;
}
XmlDocument doc = new XmlDocument();
doc.LoadXml("<?xml version=\"1.0\"?><ExperimentalData><Root></Root></ExperimentalData>");
XmlElement root = doc.GetElementsByTagName("Root")[0] as XmlElement;
XmlAttribute att = doc.CreateAttribute("uid");
att.Value = Guid.NewGuid() + "";
root.Attributes.Append(att);
att = doc.CreateAttribute("time");
att.Value = DateTime.Now + "";
root.Attributes.Append(att);
XmlElement descr = doc.CreateElement("ParametersDescription");
root.AppendChild(descr);
for (int i = 0; i < meas.Count; i++)
{
IMeasure m = meas[i] as IMeasure;
XmlElement e = doc.CreateElement("ParameterDescription");
descr.AppendChild(e);
att = doc.CreateAttribute("id");
att.Value = i + "";
e.Attributes.Append(att);
att = doc.CreateAttribute("name");
att.Value = m.Name;
e.Attributes.Append(att);
}
XmlElement results = doc.CreateElement("Results");
root.AppendChild(results);
for (int i = 0; i < r[0]; i++)
{
XmlElement result = doc.CreateElement("Result");
results.AppendChild(result);
for (int j = 0; j < meas.Count; j++)
{
IMeasure mea = meas[j] as IMeasure;
XmlElement par = doc.CreateElement("Parameter");
result.AppendChild(par);
att = doc.CreateAttribute("id");
att.Value = j + "";
par.Attributes.Append(att);
att = doc.CreateAttribute("value");
object[] o = mea.Parameter() as object[];
att.Value = o[i] + "";
par.Attributes.Append(att);
}
}
return doc;
}
#endregion
#region Xml
/*public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("DataConsumer");
XmlAttribute attr = doc.CreateAttribute("Type");
attr.Value = type + "";
el.Attributes.Append(attr);
if (ConsumerType == (int)ElectromagneticUI.ButtonKinds.GraphConsumer)
{
Form form = control.LabelForm;
if (form != null)
{
IXmlElementCreator xml = form as IXmlElementCreator;
XmlElement plotter = xml.CreateXml(doc);
el.AppendChild(plotter);
}
}
return el;
}*/
#endregion
#region Public Members
/// <summary>
/// On Change input
/// </summary>
public event Action OnChangeInput
{
add { onChangeInput += value; }
remove { onChangeInput -= value; }
}
/// <summary>
/// Prepares itself
/// </summary>
public void Prepare()
{
IDesktop d = this.GetRootDesktop();
object o = rtw.Runtime;
this.FullReset();
UpdateChildrenData();
}
/// <summary>
/// Creates measurements
/// </summary>
/// <param name="argument">Argument</param>
/// <param name="values">Names of values</param>
/// <param name="series">series</param>
/// <param name="functions">functions</param>
/// <returns>Mesurements dictionary</returns>
public Dictionary<string, object> CreateMeasurements(string argument, string[] values, out ParametrizedSeries[] series,
out Dictionary<DoubleArrayFunction, IMeasure[]> functions)
{
Double a = 0;
functions = new Dictionary<DoubleArrayFunction, IMeasure[]>();
series = null;
if (argument == null | values == null)
{
return null;
}
IMeasure arg = null;
if (argument.Equals("Time"))
{
arg = DataPerformer.StaticExtensionDataPerformerBase.Factory.TimeProvider.TimeMeasure;
}
else
{
arg = this.FindMeasure(argument, false);
}
Dictionary<string, object> d = new Dictionary<string, object>();
List<ParametrizedSeries> m = new List<ParametrizedSeries>();
foreach (string key in values)
{
object o = null;
IMeasure val = this.FindMeasure(key, false);
object t = val.Type;
if (t.Equals(a))
{
ParametrizedSeries ps = new ParametrizedSeries(MeasureWrapper.CreateValueHolder(arg), MeasureWrapper.CreateValueHolder(val));
m.Add(ps);
o = ps;
}
else
{
DoubleArrayFunction f = new DoubleArrayFunction(t);
functions[f] = new IMeasure[] { arg, val };
o = f;
}
d[key] = o;
}
series = m.ToArray();
Prepare();
return d;
}
/// <summary>
/// Checks whether exeption is caused by interruption
/// </summary>
/// <param name="e">The exception</param>
/// <returns>True in case of interruption and false oterwise</returns>
public static bool IsInterrupted(Exception e)
{
return e.Message.Equals(Interrupted);
}
/// <summary>
/// Performs action with fixed step
/// </summary>
/// <param name="start">Start time</param>
/// <param name="step">Step</param>
/// <param name="count">Count of steps</param>
/// <param name="argument">Argument</param>
/// <param name="values">Values</param>
/// <param name="series">Series</param>
/// <param name="functions">Functions</param>
/// <param name="stop">Stop function</param>
/// <returns>Result of simulation</returns>
public Dictionary<string, object> PerformFixed(double start, double step, int count, string argument, string[] values,
out ParametrizedSeries[] series,
out Dictionary<DoubleArrayFunction, IMeasure[]> functions, Func<bool> stop)
{
try
{
series = null;
functions = null;
Dictionary<string, object> dic = CreateMeasurements(argument, values, out series, out functions);
if (dic == null)
{
return null;
}
PerformFixed(start, step, count, argument, values, series, functions, stop);
return dic;
}
catch (Exception ex)
{
if (!ex.IsFiction())
{
ex.ShowError(10);
this.Throw(ex);
}
}
series = null;
functions = null;
return null;
}
/// <summary>
/// Performs action with fixed step
/// </summary>
/// <param name="argument">Argument</param>
/// <param name="values">Values</param>
/// <param name="stop">Stop function</param>
/// <returns>Action result</returns>
public Dictionary<string, object> PerformFixed(string argument, string[] values, Func<bool> stop)
{
return PerformFixed(start, step, steps, argument, values, stop);
}
/// <summary>
/// Performs action with array of arguments
/// </summary>
/// <param name="array">Array of arguments</param>
/// <param name="argument">Argument</param>
/// <param name="values">Values</param>
/// <param name="series">Series</param>
/// <param name="functions">Functions</param>
/// <param name="stop">Stop function</param>
/// <returns>Result of simulation</returns>
public Dictionary<string, object> PerformArray(Array array, string argument, string[] values,
out ParametrizedSeries[] series,
out Dictionary<DoubleArrayFunction, IMeasure[]> functions, Func<bool> stop)
{
try
{
series = null;
functions = null;
Dictionary<string, object> dic = CreateMeasurements(argument, values, out series, out functions);
if (dic == null)
{
return null;
}
PerformArray(array, argument, values, series, functions, stop);
return dic;
}
catch (Exception ex)
{
ex.ShowError(10);
this.Throw(ex);
}
series = null;
functions = null;
return null;
}
/// <summary>
/// Performs action with array of arguments
/// </summary>
/// <param name="array">Array</param>
/// <param name="argument">Argument</param>
/// <param name="values">Values</param>
/// <param name="stop">Stop function</param>
/// <returns>Result of simulation</returns>
public Dictionary<string, object> PerformArray(Array array, string argument, string[] values, Func<bool> stop)
{
ParametrizedSeries[] series = null;
Dictionary<DoubleArrayFunction, IMeasure[]> functions = null;
return PerformArray(array, argument, values, out series, out functions, stop);
}
/// <summary>
/// Throws interrupted exeption
/// </summary>
public static void Interrupt()
{
throw new FictionException(Interrupted);
}
/// <summary>
/// Performs operation with fixed step
/// </summary>
/// <param name="start">Start time</param>
/// <param name="step">Step</param>
/// <param name="count">Count of steps</param>
/// <param name="argument">Argument</param>
/// <param name="values">Values</param>
/// <param name="stop">The stop function</param>
/// <returns>Dictionary of performed result</returns>
public Dictionary<string, object> PerformFixed(double start, double step, int count,
string argument, string[] values, Func<bool> stop)
{
ParametrizedSeries[] series = null;
Dictionary<DoubleArrayFunction, IMeasure[]> functions = null;
return PerformFixed(start, step, steps, argument, values, out series, out functions, stop);
}
/// <summary>
/// Aliases of this object and all its children
/// </summary>
///
public virtual List<string> AllAliases
{
get
{
List<string> a = new List<string>();
this.GetAliases(a, null);
return a;
}
}
/// <summary>
/// Controls of graph
/// </summary>
public ArrayList GraphControls
{
get
{
return graphControls;
}
set
{
graphControls = value;
}
}
/// <summary>
/// Adds measurements provider
/// </summary>
/// <param name="measurements">Provider to add</param>
public void Add(IMeasurements measurements)
{
if (measurementsData.Contains(measurements))
{
this.Throw("Measurements aldeady exists");
}
measurementsData.Add(measurements);
onChangeInput();
}
/// <summary>
/// Removes target arrow
/// </summary>
/// <param name="arrow">Arrow to remove</param>
public void Remove(IMeasurements arrow)
{
measurementsData.Remove(arrow);
onChangeInput();
}
/// <summary>
/// Updates chidren measurements
/// </summary>
public void UpdateChildrenData()
{
if (isUpdated)
{
return;
}
foreach (IMeasurements m in measurementsData)
{
try
{
if (m is IDataConsumer)
{
IDataConsumer dc = m as IDataConsumer;
dc.UpdateChildrenData();
}
m.UpdateMeasurements();
}
catch (Exception e)
{
e.ShowError(10);
this.Throw(e);
}
}
}
/// <summary>
/// Resets measurements
/// </summary>
public void Reset()
{
this.FullReset();
}
/// <summary>
/// Count of providers
/// </summary>
public int Count
{
get
{
return measurementsData.Count;
}
}
/// <summary>
/// Arrow of n th provider
/// </summary>
public IMeasurements this[int n]
{
get
{
return measurementsData[n];
}
}
/// <summary>
/// Type of consumer
/// </summary>
public int ConsumerType
{
get
{
return type;
}
}
/// <summary>
/// Shows, wreather the object is updated
/// </summary>
public bool IsUpdated
{
get
{
return isUpdated;
}
set
{
isUpdated = value;
}
}
/// <summary>
/// Start
/// </summary>
public double Start
{
get
{
return start;
}
set
{
start = value;
}
}
/// <summary>
/// Step
/// </summary>
public double Step
{
get
{
return step;
}
set
{
step = value;
}
}
/// <summary>
/// Number of steps
/// </summary>
public int Steps
{
get
{
return steps;
}
set
{
steps = value;
}
}
/// <summary>
/// Tests desktop
/// </summary>
/// <param name="desktop">Desktop for testing</param>
public static void Test(IDesktop desktop)
{
IEnumerable<ICategoryObject> objs = desktop.CategoryObjects;
foreach (object o in objs)
{
if (o.GetType().FullName.Equals("DataPerformer.DataConsumer"))
{
DataConsumer c = o as DataConsumer;
c.test(desktop);
}
}
}
#endregion
#region Private Members
private void PerformArray(Array array, string argument, string[] values,
ParametrizedSeries[] series,
Dictionary<DoubleArrayFunction, IMeasure[]> functions, Func<bool> stop)
{
this.PerformArray(array, this.GetRootDesktop(), DataPerformer.StaticExtensionDataPerformerBase.Factory.TimeProvider,
DifferentialEquationProcessor.Processor, 0, () =>
{
if (stop())
{
Interrupt();
}
UpdateChildrenData();
foreach (ParametrizedSeries s in series)
{
s.Step();
}
foreach (DoubleArrayFunction f in functions.Keys)
{
IMeasure[] mm = functions[f];
double xx = (double)mm[0].Parameter();
f[xx] = mm[1].Parameter();
}
}, null
);
}
private void PerformFixed(double start, double step, int count, string argument, string[] values,
ParametrizedSeries[] series,
Dictionary<DoubleArrayFunction, IMeasure[]> functions, Func<bool> stop)
{
this.PerformFixed(start, step, count, DataPerformer.StaticExtensionDataPerformerBase.Factory.TimeProvider,
DifferentialEquationProcessor.Processor, this.GetRootDesktop(), 0, delegate()
{
if (stop())
{
Interrupt();
}
foreach (ParametrizedSeries s in series)
{
s.Step();
}
foreach (DoubleArrayFunction f in functions.Keys)
{
IMeasure[] mm = functions[f];
double xx = (double)mm[0].Parameter();
f[xx] = mm[1].Parameter();
}
}
);
}
private void test(IDesktop desktop)
{
IDifferentialEquationProcessor processor = DifferentialEquationProcessor.Processor;
/* IDataPerformerRuntimeFactory str = StaticDataPerformer.Factory;
if (str is IStep)
{
st = str as IStep;
}
for (int i = 0; i < steps; i++)
{
if (st != null)
{
st.Step = i;
}
if (i == 0)
{
desktop.StartAll(start);
}
desktop.UpdateAll();
StaticDataPerformerExtension.Time = start + i * step;
if (i > 0 & processor != null)
{
processor.Step(start + i * step - step, start + i * step);
}
StaticDataPerformerExtension.Time = start + i * step;
UpdateChildrenData();
desktop.ResetUpdatedMeasurements();
}*/
}
/// <summary>
/// Initialization
/// </summary>
private void initialize()
{
measurementsData = new List<IMeasurements>();
}
#endregion
}
}