source: java/main/src/main/java/com/framsticks/experiment/Simulator.java @ 193

Last change on this file since 193 was 193, checked in by Maciej Komosinski, 10 years ago

Set svn:eol-style native for all textual files

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1package com.framsticks.experiment;
2
3import com.framsticks.communication.File;
4import com.framsticks.communication.queries.NeedFile;
5import com.framsticks.communication.queries.NeedFileAcceptor;
6import com.framsticks.params.AccessOperations;
7import com.framsticks.params.CastFailure;
8import com.framsticks.params.EventListener;
9import com.framsticks.params.FramsClass;
10import com.framsticks.params.UniqueObject;
11import com.framsticks.params.annotations.FramsClassAnnotation;
12import com.framsticks.params.annotations.ParamAnnotation;
13import com.framsticks.params.types.BooleanParam;
14import com.framsticks.params.types.EventParam;
15import com.framsticks.params.types.ProcedureParam;
16import com.framsticks.remote.RemoteTree;
17import com.framsticks.structure.Path;
18import com.framsticks.structure.Tree;
19import com.framsticks.structure.messages.ListChange;
20import com.framsticks.structure.messages.ValueChange;
21import com.framsticks.util.ExceptionHandler;
22import com.framsticks.util.FramsticksException;
23import com.framsticks.util.dispatching.AbstractJoinable;
24import com.framsticks.util.dispatching.Dispatcher;
25import com.framsticks.util.dispatching.Dispatching;
26import com.framsticks.util.dispatching.FutureHandler;
27import com.framsticks.util.dispatching.Future;
28import com.framsticks.util.dispatching.Joinable;
29import com.framsticks.util.dispatching.JoinableParent;
30import com.framsticks.util.dispatching.JoinableState;
31import com.framsticks.util.dispatching.RunAt;
32import com.framsticks.util.dispatching.ThrowExceptionHandler;
33import com.framsticks.util.lang.Holder;
34import java.util.concurrent.atomic.AtomicInteger;
35import org.apache.logging.log4j.LogManager;
36import org.apache.logging.log4j.Logger;
37import static com.framsticks.params.ParamsUtil.arguments;
38import static com.framsticks.params.ParamsUtil.getParam;
39import static com.framsticks.structure.TreeOperations.*;
40
41@FramsClassAnnotation
42public final class Simulator extends AbstractJoinable implements Dispatcher<Simulator>, JoinableParent, UniqueObject, ExceptionHandler {
43
44        private static final Logger log = LogManager.getLogger(Simulator.class);
45
46        protected String uid;
47
48        protected final RemoteTree remoteTree;
49        protected final Path simulatorPath;
50        protected final FramsClass simulatorClass;
51        protected final Experiment experiment;
52        protected final EventListener<ValueChange> runningListener;
53
54        /**
55         *
56         */
57        public Simulator(Experiment experiment, RemoteTree remoteTree, Path simulatorPath) {
58                super();
59                this.remoteTree = remoteTree;
60                this.simulatorPath = simulatorPath.assureResolved();
61                this.experiment = experiment;
62                this.simulatorClass = getFramsClass(simulatorPath);
63
64                assert remoteTree.isActive();
65                assert experiment.isActive();
66
67                log.info("simulator ready {}", this);
68
69                runningListener = new EventListener<ValueChange>() {
70                        @Override
71                        public void action(ValueChange argument) {
72                                try {
73                                        boolean running = getParam(simulatorClass, "running", BooleanParam.class).reassign(argument.value, null).getValue();
74                                        log.debug("running state of {} changed: {}", Simulator.this, running);
75                                        if (!running) {
76                                                Simulator.this.experiment.simulators.fireChildrenChange(Simulator.this, ListChange.Action.Modify, "ready", "stoped");
77                                        }
78                                } catch (CastFailure e) {
79                                        log.error("failure: ", e);
80                                }
81                        }
82                };
83
84                addListener(simulatorPath, getParam(simulatorClass, "running_changed", EventParam.class), runningListener, ValueChange.class, new Future<Void>(this) {
85                        @Override
86                        protected void result(Void result) {
87                                log.debug("running listener for {} registered", this);
88                        }
89                });
90        }
91
92        @ParamAnnotation
93        public String getAddress() {
94                return remoteTree.getAddress();
95        }
96
97        @Override
98        @ParamAnnotation
99        public String getName() {
100                return getAddress();
101        }
102
103        @Override
104        @ParamAnnotation
105        public String getUid() {
106                return uid;
107        }
108
109        @Override
110        public void setUid(String uid) {
111                this.uid = uid;
112        }
113
114        /**
115         * @return the tree
116         */
117        @ParamAnnotation
118        public RemoteTree getRemoteTree() {
119                return remoteTree;
120        }
121
122        /**
123         * @return the simulatorPath
124         */
125        public Path getSimulatorPath() {
126                return simulatorPath;
127        }
128
129        /**
130         * @return the simulatorClass
131         */
132        public FramsClass getSimulatorClass() {
133                return simulatorClass;
134        }
135
136        @Override
137        protected void joinableStart() {
138                Dispatching.use(remoteTree, this);
139        }
140
141        @Override
142        protected void joinableInterrupt() {
143                Dispatching.drop(remoteTree, this);
144
145        }
146
147        @Override
148        protected void joinableFinish() {
149
150        }
151
152        @Override
153        protected void joinableJoin() throws InterruptedException {
154                Dispatching.join(remoteTree);
155        }
156
157        @ParamAnnotation(paramType = ProcedureParam.class)
158        public void init() {
159                log.debug("initializing simulator {}", this);
160                call(simulatorPath, "init", arguments(), Object.class, Future.doNothing(Object.class, this));
161        }
162
163        @ParamAnnotation(paramType = ProcedureParam.class)
164        public void start() {
165                log.debug("starting simulator {}", this);
166                call(simulatorPath, "start", arguments(), Object.class, Future.doNothing(Object.class, this));
167        }
168
169        @ParamAnnotation(paramType = ProcedureParam.class)
170        public void stop() {
171                log.debug("stoping simulator {}", this);
172                call(simulatorPath, "stop", arguments(), Object.class, Future.doNothing(Object.class, this));
173        }
174
175        @ParamAnnotation(paramType = ProcedureParam.class)
176        public void abort() {
177                assert isActive();
178                log.info("explicitly aborting {}", this);
179                experiment.removeSimulator(this);
180                interruptJoinable();
181        }
182
183        @Override
184        public void childChangedState(Joinable joinable, JoinableState state) {
185                proceedToState(state);
186        }
187
188        @Override
189        public void handle(FramsticksException exception) {
190                experiment.handle(new FramsticksException().msg("exception caught in simulator").arg("simulator", this).cause(exception));
191        }
192
193        @Override
194        public boolean isActive() {
195                return experiment.isActive();
196        }
197
198        @SuppressWarnings({ "rawtypes", "unchecked" })
199        @Override
200        public void dispatch(RunAt<? extends Simulator> runnable) {
201                experiment.dispatch((RunAt) runnable);
202        }
203
204        protected final AtomicInteger netloadIdCounter = new AtomicInteger();
205
206        public <N> void netload(final N net, final FutureHandler<Object> future) {
207                final String netloadId = "netload" + netloadIdCounter.getAndIncrement();
208
209                final File file = AccessOperations.convert(File.class, net, getRemoteTree().getRegistry());
210                log.debug("uploading file {} to {} identified by {}", file, simulatorPath, netloadId);
211
212                final Holder<NeedFileAcceptor> acceptor = new Holder<>();
213                final Tree tree = simulatorPath.getTree();
214
215                acceptor.set(new NeedFileAcceptor() {
216
217                        @Override
218                        public boolean acceptNeed(NeedFile needFile) {
219                                if (!needFile.getDescription().equals(netloadId)) {
220                                        return false;
221                                }
222                                log.debug("accepting netload {}", netloadId);
223                                needFile.getFuture().pass(file);
224                                tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
225
226                                        @Override
227                                        protected void runAt() {
228                                                tree.removeNeedFileAcceptor(acceptor.get());
229                                        }
230                                });
231                                return true;
232                        }
233
234                });
235
236                simulatorPath.getTree().addNeedFileAcceptor(Integer.MIN_VALUE, acceptor.get());
237
238                call(simulatorPath, getParam(simulatorPath, "netload_id", ProcedureParam.class), arguments(netloadId), Object.class, new Future<Object>(future) {
239
240                        @Override
241                        protected void result(Object result) {
242                                log.debug("netload of {} done", file);
243                                future.pass(result);
244                        }
245                });
246
247        }
248
249        public <N> void netsave(Class<N> netJavaClass, final FutureHandler<N> futureNet) {
250                call(simulatorPath, getParam(simulatorPath, "netsave", ProcedureParam.class), arguments(), netJavaClass, new Future<N>(futureNet) {
251
252                        @Override
253                        protected void result(N net) {
254                                log.debug("netsave of {} done", net);
255                                futureNet.pass(net);
256                        }
257                });
258        }
259}
Note: See TracBrowser for help on using the repository browser.