View Javadoc

1   package cz.cuni.amis.pogamut.base.agent.navigation.impl;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.logging.Level;
6   import java.util.logging.Logger;
7   
8   import cz.cuni.amis.pogamut.base.agent.navigation.IPathExecutor;
9   import cz.cuni.amis.pogamut.base.agent.navigation.IPathExecutorState;
10  import cz.cuni.amis.pogamut.base.agent.navigation.IPathFuture;
11  import cz.cuni.amis.pogamut.base.agent.navigation.IStuckDetector;
12  import cz.cuni.amis.pogamut.base.agent.navigation.PathExecutorState;
13  import cz.cuni.amis.utils.flag.Flag;
14  import cz.cuni.amis.utils.flag.ImmutableFlag;
15  import cz.cuni.amis.utils.future.FutureStatus;
16  
17  /**
18   * Stub implementation of the {@link IPathExecutor} that implements several trivial methods from the
19   * interface leaving the important one to be implemented by descendants.
20   * <p><p>
21   * Methods that need to be implemented are:
22   * {@link AbstractPathExecutor#followPath(IPathFuture)}, {@link AbstractPathExecutor#getPathFuture()}, {@link AbstractPathExecutor#getPathElementIndex()}
23   * and {@link AbstractPathExecutor#stop()}). Note that these methods must correctly set the path executor state
24   * according to javadoc in {@link PathExecutorState}. 
25   * 
26   * @author Jimmy
27   *
28   * @param <PATH_ELEMENT>
29   */
30  public abstract class AbstractPathExecutor<PATH_ELEMENT> implements IPathExecutor<PATH_ELEMENT> {
31  
32  	protected Flag<IPathExecutorState> state = new Flag<IPathExecutorState>(new BasePathExecutorState(PathExecutorState.INSTANTIATED));
33  	
34  	protected List<IStuckDetector> stuckDetectors = new ArrayList<IStuckDetector>();
35  	
36  	protected Logger log;
37  	
38  	public AbstractPathExecutor() {
39  		this(null);
40  	}
41  	
42  	public AbstractPathExecutor(Logger log) {
43  		this.log = log;
44  	}
45  	
46  	@Override
47  	public Logger getLog() {
48  		return log;
49  	}
50  
51  	/**
52  	 * Sets logger to be used by the path executor.
53  	 * @param log
54  	 */
55  	public void setLog(Logger log) {
56  		this.log = log;
57  	}
58  
59  	/**
60  	 * Simple method that sets new {@link AbstractPathExecutor} state into {@link AbstractPathExecutor#state}.
61  	 * @param newState
62  	 */
63  	protected void switchState(IPathExecutorState newState) {
64  		if (log != null && log.isLoggable(Level.FINEST)) log.finest("new state " + newState.getState());
65  		state.setFlag(newState);
66  	}
67  	
68  	@Override
69  	public ImmutableFlag<IPathExecutorState> getState() {
70  		return state.getImmutable();
71  	}
72  	
73  	@Override
74  	public void addStuckDetector(IStuckDetector stuckDetector) {
75  		stuckDetectors.add(stuckDetector);
76  	}
77  	
78  	@Override
79  	public void removeStuckDetector(IStuckDetector stuckDetector) {
80  		stuckDetectors.remove(stuckDetector);
81  	}
82  	
83  	@Override
84  	public void removeAllStuckDetectors() {
85  		stuckDetectors.clear();
86  	}
87  	
88  	@Override
89  	public boolean inState(PathExecutorState... states) {
90  		IPathExecutorState current = getState().getFlag();
91  		for (PathExecutorState state : states) {
92  			if (state == current.getState()) return true;
93  		}
94  		return false;
95  	}
96  
97  	@Override
98  	public boolean notInState(PathExecutorState... states) {
99  		IPathExecutorState current = getState().getFlag();
100 		for (PathExecutorState state : states) {
101 			if (state == current.getState()) return false;
102 		}
103 		return true;
104 	}
105 	
106 	@Override
107 	public List<PATH_ELEMENT> getPath() {
108 		if (!isExecuting()) return null;
109 		IPathFuture<PATH_ELEMENT> pathFuture = getPathFuture();
110 		if (pathFuture == null) return null;
111 		if (pathFuture.getStatus() == FutureStatus.FUTURE_IS_READY) {
112 			return pathFuture.get();
113 		} else {
114 			return null;
115 		}
116 	}
117 	
118 	/**
119 	 * Returns correct path element only if the {@link AbstractPathExecutor#getPathElementIndex()} is in the range
120 	 * of {@link AbstractPathExecutor#getPath()}. Otherwise, returns null.
121 	 * 
122 	 * @return current path element the executor is navigating to or null
123 	 */
124 	@Override
125 	public PATH_ELEMENT getPathElement() {
126 		int index = getPathElementIndex();
127 		if (index < 0) return null;
128 		List<PATH_ELEMENT> path = getPath();
129 		if (path == null) return null;
130 		if (index > 0 && index < path.size()) return path.get(index);
131 		return null;
132 	}
133 	
134 	@Override
135 	public boolean isExecuting() {
136 		return inState(PathExecutorState.FOLLOW_PATH_CALLED, PathExecutorState.PATH_COMPUTED, PathExecutorState.SWITCHED_TO_ANOTHER_PATH_ELEMENT);
137 	}
138 
139 	@Override
140 	public boolean isTargetReached() {
141 		return state.getFlag().getState() == PathExecutorState.TARGET_REACHED;
142 	}
143 	
144 	@Override
145 	public boolean isStuck() {
146 		return state.getFlag().getState() == PathExecutorState.STUCK;
147 	}
148 	
149 	@Override
150 	public boolean isPathUnavailable() {
151 		return state.getFlag().getState() == PathExecutorState.PATH_COMPUTATION_FAILED;
152 	}
153 	
154 	@Override
155 	public abstract void followPath(IPathFuture<? extends PATH_ELEMENT> path);
156 
157 	@Override
158 	public abstract IPathFuture<PATH_ELEMENT> getPathFuture();
159 
160 	@Override
161 	public abstract int getPathElementIndex();
162 
163 	@Override
164 	public abstract void stop();
165 	
166 }