[171] | 1 | using System; |
---|
| 2 | using System.Collections.Generic; |
---|
| 3 | using System.Linq; |
---|
| 4 | using System.Text; |
---|
| 5 | |
---|
| 6 | namespace BCMToolbox |
---|
| 7 | { |
---|
| 8 | [Serializable] |
---|
| 9 | public abstract class StimulatorBase |
---|
| 10 | { |
---|
| 11 | protected Dictionary<string, object> __parameters = new Dictionary<string, object>(); |
---|
| 12 | |
---|
| 13 | [NonSerialized] |
---|
| 14 | INetwork __bound = null; |
---|
| 15 | int __startTick = 0; |
---|
| 16 | public const string STIMULUS_LENGTH = "Stimulus Length"; |
---|
| 17 | public const string STIMULUS_START = "Stimulus Start"; |
---|
| 18 | public const string STIMULUS_NULL = "null"; |
---|
| 19 | |
---|
| 20 | public abstract string[] GetParameters(); |
---|
| 21 | protected abstract void Apply(); |
---|
| 22 | protected INetwork Bound |
---|
| 23 | { |
---|
| 24 | get |
---|
| 25 | { |
---|
| 26 | return __bound; |
---|
| 27 | } |
---|
| 28 | } |
---|
| 29 | |
---|
| 30 | protected int ElapsedTicks |
---|
| 31 | { |
---|
| 32 | get |
---|
| 33 | { |
---|
| 34 | return __bound.Ticks - __startTick; |
---|
| 35 | } |
---|
| 36 | } |
---|
| 37 | |
---|
| 38 | public static double GetDouble(object o) |
---|
| 39 | { |
---|
| 40 | if (o is int) |
---|
| 41 | return (double)(int)o; |
---|
| 42 | else if (o is double) |
---|
| 43 | return (double)o; |
---|
| 44 | return double.NaN; |
---|
| 45 | } |
---|
| 46 | |
---|
| 47 | public virtual void SetParameters(Dictionary<string, object> toSet) |
---|
| 48 | { |
---|
| 49 | List<string> paramNames = new List<string>(GetParameters()); |
---|
| 50 | foreach (KeyValuePair<string, object> kvp in toSet) |
---|
| 51 | if (paramNames.Contains(kvp.Key)) |
---|
| 52 | __parameters[kvp.Key] = kvp.Value; |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | public bool IsBound |
---|
| 56 | { |
---|
| 57 | get |
---|
| 58 | { |
---|
| 59 | return __bound != null; |
---|
| 60 | } |
---|
| 61 | } |
---|
| 62 | |
---|
| 63 | public void BindToNetwork(INetwork net) |
---|
| 64 | { |
---|
| 65 | if (__bound != null) |
---|
| 66 | throw new ArgumentException("Stimulus already bound to a network."); |
---|
| 67 | |
---|
| 68 | List<string> paramNames = new List<string>(GetParameters()); |
---|
| 69 | foreach (string paramName in paramNames) |
---|
| 70 | if (!__parameters.ContainsKey(paramName)) |
---|
| 71 | throw new ArgumentException("Parameter not set: " + paramName); |
---|
| 72 | |
---|
| 73 | __bound = net; |
---|
| 74 | __bound.TickProgress += new EventHandler(__bound_TickProgress); |
---|
| 75 | __bound_TickProgress(this, EventArgs.Empty); |
---|
| 76 | } |
---|
| 77 | |
---|
| 78 | public void Unbind() |
---|
| 79 | { |
---|
| 80 | if (__bound == null) |
---|
| 81 | throw new NotSupportedException("This stimulus was not bound."); |
---|
| 82 | __bound.TickProgress -= new EventHandler(__bound_TickProgress); |
---|
| 83 | __bound = null; |
---|
| 84 | __startTick = 0; |
---|
| 85 | } |
---|
| 86 | |
---|
| 87 | protected virtual void __bound_TickProgress(object sender, EventArgs e) |
---|
| 88 | { |
---|
| 89 | if (!IsBound) |
---|
| 90 | return; |
---|
| 91 | if (__parameters.ContainsKey(STIMULUS_START)) |
---|
| 92 | { |
---|
| 93 | if (__parameters[STIMULUS_START] != null) |
---|
| 94 | { |
---|
| 95 | object start = __parameters[STIMULUS_START].ToString(); |
---|
| 96 | if (start is int) |
---|
| 97 | if (__bound.Ticks < (int)start) // not started yet |
---|
| 98 | return; |
---|
| 99 | } |
---|
| 100 | } |
---|
| 101 | |
---|
| 102 | if (__startTick == 0) |
---|
| 103 | __startTick = __bound.Ticks; |
---|
| 104 | |
---|
| 105 | Apply(); |
---|
| 106 | if (__parameters.ContainsKey(STIMULUS_LENGTH)) |
---|
| 107 | if(__parameters[STIMULUS_LENGTH] != null) |
---|
| 108 | if(__parameters[STIMULUS_LENGTH] is int) |
---|
| 109 | if (ElapsedTicks >= (int)__parameters[STIMULUS_LENGTH]) |
---|
| 110 | Unbind(); |
---|
| 111 | } |
---|
| 112 | } |
---|
| 113 | } |
---|