1 | package dk.deepthought.sidious.planner; |
2 | |
3 | import java.util.Collection; |
4 | import java.util.HashMap; |
5 | |
6 | import org.apache.commons.logging.Log; |
7 | import org.apache.commons.logging.LogFactory; |
8 | |
9 | import dk.deepthought.sidious.goalhandler.Goal; |
10 | import dk.deepthought.sidious.planner.graph.Graph; |
11 | import dk.deepthought.sidious.services.ServiceEngine; |
12 | import dk.deepthought.sidious.supportsystem.Adjustable; |
13 | import dk.deepthought.sidious.supportsystem.Repository; |
14 | import dk.deepthought.sidious.supportsystem.State; |
15 | import dk.deepthought.sidious.supportsystem.SuperLinkID; |
16 | import dk.deepthought.sidious.util.SidiousQueue; |
17 | |
18 | /** |
19 | * This class constitutes a Blackboard for the planner. Works as a liaison class |
20 | * between the <code>{@link GraphFactory}</code> and |
21 | * <code>{@link Pathfinder}</code>. |
22 | * <p> |
23 | * This class holds three <code>SidiousQueue</code> queues for calculating a |
24 | * plan: |
25 | * <ol> |
26 | * <li> extracting state and generating the graph |
27 | * <li> for processing the pathfinding |
28 | * <li> for plan generation |
29 | * </ol> |
30 | * |
31 | * @author Deepthought |
32 | * |
33 | */ |
34 | public final class PlannerEngine implements Planner { |
35 | |
36 | // XXX se på strategy pattern for at vælge kvilken pathfinder algoritme der |
37 | // skal bruges. |
38 | // Måske mest anvendeligt i spil! |
39 | |
40 | /** |
41 | * Logger for this class. |
42 | */ |
43 | private static final Log logger = LogFactory.getLog(PlannerEngine.class); |
44 | |
45 | /** |
46 | * Mapping between id and pathfinder |
47 | */ |
48 | private final HashMap<SuperLinkID, Pathfinder> idToPathfinder = new HashMap<SuperLinkID, Pathfinder>(); |
49 | |
50 | /** |
51 | * private singleton instance. |
52 | */ |
53 | private static final Planner INSTANCE = new PlannerEngine(); |
54 | |
55 | /** |
56 | * Queue to facilitate generation of the graph. |
57 | */ |
58 | private SidiousQueue<Goal> graphFactoryQueue = new SidiousQueue<Goal>( |
59 | "graphFactoryQueue") { |
60 | |
61 | protected void process(Goal item) { |
62 | State start = ServiceEngine.getCurrentState(); |
63 | pathfinderQueue.enqueue(GraphFactory.makeGraph(item.getOrigin(), |
64 | start, item.getGoalState())); |
65 | } |
66 | }; |
67 | |
68 | /** |
69 | * Queue to facilitate the path finding. |
70 | */ |
71 | private SidiousQueue<Graph> pathfinderQueue = new SidiousQueue<Graph>( |
72 | "pathfinderQueue") { |
73 | |
74 | @Override |
75 | protected void process(Graph item) { |
76 | Pathfinder p = new AStarAlgorithm(); |
77 | idToPathfinder.put(item.getId(), p); |
78 | item.getGoalVertex().getState(); |
79 | p.search(item); |
80 | planGeneratorQueue.enqueue(item); |
81 | } |
82 | }; |
83 | |
84 | /** |
85 | * Queue to handle the generation of a plan from a searched graph. |
86 | */ |
87 | private SidiousQueue<Graph> planGeneratorQueue = new SidiousQueue<Graph>( |
88 | "planGeneratorQueue") { |
89 | |
90 | @Override |
91 | protected void process(Graph item) { |
92 | Plan plan = PlanGenerator.generatePlan(item); |
93 | deliverPlan(plan); |
94 | } |
95 | }; |
96 | |
97 | /** |
98 | * Private constructor, to facilitate singleton. |
99 | */ |
100 | private PlannerEngine() { |
101 | } |
102 | |
103 | /** |
104 | * Delivers the finished plan to the blackboard. |
105 | * |
106 | * @param plan |
107 | * the finished plan |
108 | */ |
109 | private void deliverPlan(Plan plan) { |
110 | Repository.getBlackboard().deliverResult(plan); |
111 | } |
112 | |
113 | /** |
114 | * Returns the adjustables of the specified requester. |
115 | * |
116 | * @param requester |
117 | * the requester |
118 | * @return the adjustables of the requester |
119 | */ |
120 | public static Collection<Adjustable> getAdjustables(SuperLinkID requester) { |
121 | return Repository.getBlackboard().getRequester(requester) |
122 | .getAdjustables(); |
123 | } |
124 | |
125 | /* |
126 | * (non-Javadoc) |
127 | * |
128 | * @see dk.deepthought.sidious.planner.Planner#stop(dk.deepthought.sidious.supportsystem.SuperLinkID) |
129 | */ |
130 | public void stop(SuperLinkID id) { |
131 | if (logger.isDebugEnabled()) { |
132 | logger.debug("stop(SuperLinkID id=" + id |
133 | + ") - attempting to stop planning"); |
134 | } |
135 | if (idToPathfinder.containsKey(id)) { |
136 | Pathfinder pathfinder = idToPathfinder.get(id); |
137 | pathfinder.cancel(); |
138 | idToPathfinder.remove(id); |
139 | } |
140 | if (logger.isDebugEnabled()) { |
141 | logger.debug("stop(SuperLinkID id=" + id + ") - stopped planning"); |
142 | } |
143 | } |
144 | |
145 | /* |
146 | * (non-Javadoc) |
147 | * |
148 | * @see dk.deepthought.sidious.planner.Planner#requestPlan(dk.deepthought.sidious.goalhandler.Goal) |
149 | */ |
150 | public void requestPlan(Goal goal) { |
151 | if (goal == null) { |
152 | throw new IllegalArgumentException("null not valid goal"); |
153 | } |
154 | graphFactoryQueue.enqueue(goal); |
155 | } |
156 | |
157 | /** |
158 | * Returns the singleton instance. |
159 | * |
160 | * @return the singleton instance |
161 | */ |
162 | public static Planner getInstance() { |
163 | return INSTANCE; |
164 | } |
165 | |
166 | } |