1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.piccolo.sprite.statemachine;
25
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28
29 import org.apache.commons.scxml.Context;
30 import org.apache.commons.scxml.ErrorReporter;
31 import org.apache.commons.scxml.Evaluator;
32 import org.apache.commons.scxml.EventDispatcher;
33 import org.apache.commons.scxml.SCXMLExecutor;
34 import org.apache.commons.scxml.SCXMLListener;
35 import org.apache.commons.scxml.TriggerEvent;
36
37 import org.apache.commons.scxml.env.SimpleDispatcher;
38
39 import org.apache.commons.scxml.env.jexl.JexlContext;
40 import org.apache.commons.scxml.env.jexl.JexlEvaluator;
41
42 import org.apache.commons.scxml.model.ModelException;
43 import org.apache.commons.scxml.model.SCXML;
44 import org.apache.commons.scxml.model.Transition;
45 import org.apache.commons.scxml.model.TransitionTarget;
46
47
48
49
50
51
52
53
54
55
56
57
58 final class StateMachineSupport
59 {
60
61 private final Object delegator;
62
63
64 private final SCXMLExecutor executor;
65
66
67
68
69
70
71
72
73
74
75
76 StateMachineSupport(final Object delegator, final SCXML stateMachine)
77 {
78 if (delegator == null)
79 {
80 throw new IllegalArgumentException("delegator must not be null");
81 }
82 if (stateMachine == null)
83 {
84 throw new IllegalArgumentException("stateMachine must not be null");
85 }
86 this.delegator = delegator;
87
88 Evaluator evaluator = new JexlEvaluator();
89 EventDispatcher dispatcher = new SimpleDispatcher();
90 ErrorReporter errorReporter = new NoopErrorReporter();
91 Context rootContext = new JexlContext();
92 SCXMLListener listener = new SCXMLListener()
93 {
94 @Override
95 public void onEntry(final TransitionTarget entered)
96 {
97 invoke(entered.getId());
98 }
99
100 @Override
101 public void onExit(final TransitionTarget exited)
102 {
103
104 }
105
106 @Override
107 public void onTransition(final TransitionTarget to,
108 final TransitionTarget from,
109 final Transition transition)
110 {
111
112 }
113 };
114
115 executor = new SCXMLExecutor(evaluator, dispatcher, errorReporter);
116 executor.setStateMachine(stateMachine);
117 executor.setSuperStep(false);
118 executor.setRootContext(rootContext);
119 executor.addListener(stateMachine, listener);
120
121 try
122 {
123 executor.go();
124 }
125 catch (ModelException e)
126 {
127
128 }
129 }
130
131
132
133
134
135 void resetStateMachine()
136 {
137 try
138 {
139 executor.reset();
140 }
141 catch (ModelException e)
142 {
143
144 }
145 }
146
147
148
149
150
151
152
153 void fireStateMachineEvent(final String eventName)
154 {
155 if (eventName == null)
156 {
157 throw new IllegalArgumentException("eventName must not be null");
158 }
159 try
160 {
161 TriggerEvent event = new TriggerEvent(eventName, TriggerEvent.SIGNAL_EVENT, null);
162 executor.triggerEvents(new TriggerEvent[] { event });
163 }
164 catch (ModelException e)
165 {
166
167 }
168 }
169
170
171
172
173
174
175 SCXMLExecutor getExecutor()
176 {
177 return executor;
178 }
179
180
181
182
183
184
185
186
187
188 private void invoke(final String methodName)
189 {
190 try
191 {
192 Class<?> c = delegator.getClass();
193 Method method = c.getDeclaredMethod(methodName, new Class[0]);
194 method.setAccessible(true);
195 method.invoke(delegator, new Object[0]);
196 }
197 catch (SecurityException se)
198 {
199
200 }
201 catch (NoSuchMethodException nsme)
202 {
203
204 }
205 catch (IllegalArgumentException iae)
206 {
207
208 }
209 catch (IllegalAccessException iae)
210 {
211
212 }
213 catch (InvocationTargetException ite)
214 {
215
216 }
217 }
218
219
220
221
222 private class NoopErrorReporter
223 implements ErrorReporter
224 {
225
226 @Override
227 public void onError(final String errorCode,
228 final String errorDetail,
229 final Object errorContext)
230 {
231
232 }
233 }
234 }