using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BCMToolbox { [Serializable] public abstract class StimulatorBase { protected Dictionary __parameters = new Dictionary(); [NonSerialized] INetwork __bound = null; int __startTick = 0; public const string STIMULUS_LENGTH = "Stimulus Length"; public const string STIMULUS_START = "Stimulus Start"; public const string STIMULUS_NULL = "null"; public abstract string[] GetParameters(); protected abstract void Apply(); protected INetwork Bound { get { return __bound; } } protected int ElapsedTicks { get { return __bound.Ticks - __startTick; } } public static double GetDouble(object o) { if (o is int) return (double)(int)o; else if (o is double) return (double)o; return double.NaN; } public virtual void SetParameters(Dictionary toSet) { List paramNames = new List(GetParameters()); foreach (KeyValuePair kvp in toSet) if (paramNames.Contains(kvp.Key)) __parameters[kvp.Key] = kvp.Value; } public bool IsBound { get { return __bound != null; } } public void BindToNetwork(INetwork net) { if (__bound != null) throw new ArgumentException("Stimulus already bound to a network."); List paramNames = new List(GetParameters()); foreach (string paramName in paramNames) if (!__parameters.ContainsKey(paramName)) throw new ArgumentException("Parameter not set: " + paramName); __bound = net; __bound.TickProgress += new EventHandler(__bound_TickProgress); __bound_TickProgress(this, EventArgs.Empty); } public void Unbind() { if (__bound == null) throw new NotSupportedException("This stimulus was not bound."); __bound.TickProgress -= new EventHandler(__bound_TickProgress); __bound = null; __startTick = 0; } protected virtual void __bound_TickProgress(object sender, EventArgs e) { if (!IsBound) return; if (__parameters.ContainsKey(STIMULUS_START)) { if (__parameters[STIMULUS_START] != null) { object start = __parameters[STIMULUS_START].ToString(); if (start is int) if (__bound.Ticks < (int)start) // not started yet return; } } if (__startTick == 0) __startTick = __bound.Ticks; Apply(); if (__parameters.ContainsKey(STIMULUS_LENGTH)) if(__parameters[STIMULUS_LENGTH] != null) if(__parameters[STIMULUS_LENGTH] is int) if (ElapsedTicks >= (int)__parameters[STIMULUS_LENGTH]) Unbind(); } } }