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 | } |
---|