1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.tomgibara.pronto.control.impl;
19
20 import java.util.HashSet;
21
22 import com.tomgibara.pronto.control.Controller;
23 import com.tomgibara.pronto.control.EngineControlAdapter;
24 import com.tomgibara.pronto.state.StateEngine;
25 import com.tomgibara.pronto.util.Arguments;
26
27 /**
28 * The standard implementation of the Controller interface. It aggregates a
29 * number of ControllerParts that provide its actual functionality. This means
30 * that a single instance of this class can actually provide 'multiple'
31 * functionality based on the a settings object that implements a number of
32 * different ControllerSettings interfaces.
33 *
34 * @param <S>
35 * the type of state
36 * @param <L>
37 * the type of label
38 * @param <P>
39 * the type of parameter
40 *
41 * @author Tom Gibara
42 *
43 */
44
45 public class ControllerImpl<S, L, P> implements Controller<S, L, P> {
46
47
48
49 private final HashSet<ControllerPart> parts = new HashSet<ControllerPart>();
50
51 /**
52 * Direct package-scope access is provided so that controller parts can
53 * obtain a reference to the engine they must operate over.
54 */
55
56 final StateEngine<S, L, P> engine;
57
58 /**
59 * Direct package-scope access is provided so that controller parts can
60 * obtain a reference to the adapter they should use.
61 */
62
63 final CheckedAdapter<S, L, P> adapter;
64
65
66
67 public ControllerImpl(final StateEngine<S, L, P> engine, final EngineControlAdapter<S, L, P> adapter) {
68 Arguments.notNull(engine, "engine");
69 Arguments.notNull(adapter, "adapter");
70
71 this.engine = engine;
72 this.adapter = new CheckedAdapter<S, L, P>(adapter);
73 }
74
75
76
77 public EngineControlAdapter<S, L, P> getAdapter() {
78 return adapter.getAdapter();
79 }
80
81 public StateEngine<S, L, P> getEngine() {
82 return engine;
83 }
84
85 public void start() {
86 for (ControllerPart<S, L, P> part : parts) {
87 part.start();
88 }
89 }
90
91 public boolean stop(final long timeout) {
92 Arguments.notNegative(timeout, "timeout");
93 boolean success = true;
94 if (timeout == 0L) {
95 for (ControllerPart<S, L, P> part : parts) {
96 success = success && part.stop(0L);
97 }
98 } else {
99 final long start = System.currentTimeMillis();
100 for (ControllerPart<S, L, P> part : parts) {
101 final long now = System.currentTimeMillis();
102 success = success && part.stop(timeout - (now - start));
103 }
104 }
105 return success;
106 }
107
108
109
110 void addPart(final ControllerPart<S, L, P> part) {
111 if (part.getController() != this) throw new IllegalArgumentException("Part not made for this controller.");
112 parts.add(part);
113 }
114
115 boolean isEmpty() {
116 return parts.isEmpty();
117 }
118
119 }