DeviceDescriptor: eliminate obsolete NMEAOut kludge
[xcsoar.git] / src / Task / MapTaskManager.cpp
blob9885eea86fd69a103514b07fed99d0d8334999af
1 /* Copyright_License {
3 XCSoar Glide Computer - http://www.xcsoar.org/
4 Copyright (C) 2000-2013 The XCSoar Project
5 A detailed list of copyright holders can be found in the file "AUTHORS".
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "Task/MapTaskManager.hpp"
24 #include "Task/ProtectedTaskManager.hpp"
25 #include "Components.hpp"
26 #include "Protection.hpp"
27 #include "Engine/Task/Ordered/OrderedTask.hpp"
28 #include "Engine/Task/Ordered/Points/OrderedTaskPoint.hpp"
29 #include "Engine/Task/Factory/AbstractTaskFactory.hpp"
30 #include "Interface.hpp"
32 static const TaskBehaviour&
33 GetTaskBehaviour()
35 return CommonInterface::GetComputerSettings().task;
38 static MapTaskManager::TaskEditResult
39 AppendToTask(OrderedTask *task, const Waypoint &waypoint)
41 if (task->TaskSize()==0)
42 return MapTaskManager::NOTASK;
44 int i = task->TaskSize() - 1;
45 // skip all finish points
46 while (i >= 0) {
47 const OrderedTaskPoint &tp = task->GetPoint(i);
48 if (tp.IsSuccessorAllowed()) {
49 ++i;
50 break;
53 --i;
56 const AbstractTaskFactory &factory = task->GetFactory();
57 OrderedTaskPoint *task_point =
58 (OrderedTaskPoint *)factory.CreateIntermediate(waypoint);
59 if (task_point == NULL)
60 return MapTaskManager::UNMODIFIED;
62 bool success = i >= 0 ? task->Insert(*task_point, i) : task->Append(*task_point);
63 delete task_point;
65 if (!success)
66 return MapTaskManager::UNMODIFIED;
68 if (!task->CheckTask())
69 return MapTaskManager::INVALID;
71 return MapTaskManager::SUCCESS;
74 static MapTaskManager::TaskEditResult
75 MutateFromGoto(OrderedTask *task, const Waypoint &finish_waypoint,
76 const Waypoint &start_waypoint)
78 const AbstractTaskFactory &factory = task->GetFactory();
79 OrderedTaskPoint *start_point =
80 (OrderedTaskPoint *)factory.CreateStart(start_waypoint);
81 if (start_point == NULL)
82 return MapTaskManager::UNMODIFIED;
84 bool success = task->Append(*start_point);
85 delete start_point;
86 if (!success)
87 return MapTaskManager::UNMODIFIED;
89 OrderedTaskPoint *finish_point =
90 (OrderedTaskPoint *)factory.CreateFinish(finish_waypoint);
91 if (finish_point == NULL)
92 return MapTaskManager::UNMODIFIED;
94 success = task->Append(*finish_point);
95 delete finish_point;
97 if (!success)
98 return MapTaskManager::UNMODIFIED;
100 return MapTaskManager::MUTATED_FROM_GOTO;
103 MapTaskManager::TaskEditResult
104 MapTaskManager::AppendToTask(const Waypoint &waypoint)
106 assert(protected_task_manager != NULL);
107 ProtectedTaskManager::ExclusiveLease task_manager(*protected_task_manager);
108 TaskEditResult result = MapTaskManager::UNMODIFIED;
109 if (task_manager->GetOrderedTask().CheckTask()) {
110 OrderedTask *task = task_manager->Clone(GetTaskBehaviour());
111 result = AppendToTask(task, waypoint);
112 if (result == SUCCESS)
113 task_manager->Commit(*task);
114 delete task;
115 } else { // ordered task invalid
116 switch (task_manager->GetMode()) {
117 case TaskType::NONE:
118 case TaskType::ABORT:
119 case TaskType::ORDERED:
120 result = task_manager->DoGoto(waypoint) ? MapTaskManager::MUTATED_TO_GOTO :
121 MapTaskManager::UNMODIFIED;
122 break;
123 case TaskType::GOTO:
125 OrderedTask *task = task_manager->Clone(GetTaskBehaviour());
126 const TaskWaypoint *OldGotoTWP = task_manager->GetActiveTaskPoint();
127 if (!OldGotoTWP)
128 break;
130 const Waypoint &OldGotoWp = OldGotoTWP->GetWaypoint();
131 result = MutateFromGoto(task, waypoint, OldGotoWp);
132 if (result == MUTATED_FROM_GOTO)
133 task_manager->Commit(*task);
135 delete task;
136 break;
140 return result;
143 static MapTaskManager::TaskEditResult
144 InsertInTask(OrderedTask *task, const Waypoint &waypoint)
146 if (task->TaskSize()==0)
147 return MapTaskManager::NOTASK;
149 int i = task->GetActiveIndex();
150 /* skip all start points */
151 while (true) {
152 if (i >= (int)task->TaskSize())
153 return MapTaskManager::UNMODIFIED;
155 const OrderedTaskPoint &task_point = task->GetPoint(i);
156 if (task_point.IsPredecessorAllowed())
157 break;
159 ++i;
162 const AbstractTaskFactory &factory = task->GetFactory();
163 OrderedTaskPoint *task_point =
164 (OrderedTaskPoint *)factory.CreateIntermediate(waypoint);
165 if (task_point == NULL)
166 return MapTaskManager::UNMODIFIED;
168 bool success = task->Insert(*task_point, i);
169 delete task_point;
170 if (!success)
171 return MapTaskManager::UNMODIFIED;
172 if (!task->CheckTask())
173 return MapTaskManager::INVALID;
174 return MapTaskManager::SUCCESS;
177 MapTaskManager::TaskEditResult
178 MapTaskManager::InsertInTask(const Waypoint &waypoint)
180 assert(protected_task_manager != NULL);
181 ProtectedTaskManager::ExclusiveLease task_manager(*protected_task_manager);
182 TaskEditResult result = MapTaskManager::UNMODIFIED;
183 if (task_manager->GetOrderedTask().CheckTask()) {
184 OrderedTask *task = task_manager->Clone(GetTaskBehaviour());
186 result = InsertInTask(task, waypoint);
187 if (result == SUCCESS)
188 task_manager->Commit(*task);
189 delete task;
190 } else { // ordered task invalid
191 switch (task_manager->GetMode()) {
192 case TaskType::NONE:
193 case TaskType::ABORT:
194 case TaskType::ORDERED:
195 result = task_manager->DoGoto(waypoint) ? MapTaskManager::MUTATED_TO_GOTO :
196 MapTaskManager::UNMODIFIED;
197 break;
198 case TaskType::GOTO:
200 OrderedTask *task = task_manager->Clone(GetTaskBehaviour());
201 const TaskWaypoint *OldGotoTWP = task_manager->GetActiveTaskPoint();
202 if (!OldGotoTWP)
203 break;
204 const Waypoint &OldGotoWp = OldGotoTWP->GetWaypoint();
205 result = MutateFromGoto(task, OldGotoWp, waypoint);
206 if (result == MUTATED_FROM_GOTO)
207 task_manager->Commit(*task);
208 delete task;
209 break;
213 return result;
216 MapTaskManager::TaskEditResult
217 MapTaskManager::InsertInMatProForma(OrderedTask &task,
218 const Waypoint &waypoint)
220 assert(task.CheckTask());
221 return InsertInTask(&task, waypoint);
224 static MapTaskManager::TaskEditResult
225 ReplaceInTask(OrderedTask *task, const Waypoint &waypoint)
227 if (task->TaskSize()==0)
228 return MapTaskManager::NOTASK;
230 unsigned i = task->GetActiveIndex();
231 if (i >= task->TaskSize())
232 return MapTaskManager::UNMODIFIED;
234 task->Relocate(i, waypoint);
236 if (!task->CheckTask())
237 return MapTaskManager::INVALID;
239 return MapTaskManager::SUCCESS;
242 MapTaskManager::TaskEditResult
243 MapTaskManager::ReplaceInTask(const Waypoint &waypoint)
245 assert(protected_task_manager != NULL);
246 ProtectedTaskManager::ExclusiveLease task_manager(*protected_task_manager);
247 OrderedTask *task = task_manager->Clone(GetTaskBehaviour());
249 TaskEditResult result = ReplaceInTask(task, waypoint);
250 if (result == SUCCESS)
251 task_manager->Commit(*task);
253 delete task;
254 return result;
257 static int
258 GetUnachievedIndexInTask(const OrderedTask &task,
259 const Waypoint &waypoint)
261 if (task.TaskSize() < 2)
262 return -1;
264 unsigned last_achieved_index = task.GetLastIntermediateAchieved();
266 int TPindex = -1;
267 for (unsigned i = task.TaskSize() - 2; i > last_achieved_index; i--) {
268 const OrderedTaskPoint &tp = task.GetPoint(i);
270 if (tp.GetWaypoint() == waypoint) {
271 TPindex = i;
272 break;
275 return TPindex;
279 MapTaskManager::GetUnachievedIndexInTask(const Waypoint &waypoint)
281 assert(protected_task_manager != NULL);
282 ProtectedTaskManager::Lease task_manager(*protected_task_manager);
284 if (task_manager->GetMode() == TaskType::ORDERED) {
285 const OrderedTask &task = task_manager->GetOrderedTask();
286 return GetUnachievedIndexInTask(task, waypoint);
288 return -1;
291 static int
292 GetIndexInTask(const OrderedTask &task, const Waypoint &waypoint)
294 if (task.TaskSize() == 0)
295 return -1;
297 unsigned i = task.GetActiveIndex();
298 if (i >= task.TaskSize())
299 return -1;
301 int TPindex = -1;
302 for (unsigned i = task.TaskSize(); i--;) {
303 const OrderedTaskPoint &tp = task.GetPoint(i);
305 if (tp.GetWaypoint() == waypoint) {
306 TPindex = i;
307 break;
310 return TPindex;
314 MapTaskManager::GetIndexInTask(const Waypoint &waypoint)
316 assert(protected_task_manager != NULL);
317 ProtectedTaskManager::ExclusiveLease task_manager(*protected_task_manager);
318 if (task_manager->GetMode() == TaskType::ORDERED) {
319 const OrderedTask &task = task_manager->GetOrderedTask();
320 return GetIndexInTask(task, waypoint);
322 return -1;
325 static MapTaskManager::TaskEditResult
326 RemoveFromTask(OrderedTask *task, const Waypoint &waypoint)
328 if (task->TaskSize()==0)
329 return MapTaskManager::NOTASK;
331 int i = GetIndexInTask(*task, waypoint);
332 if (i >= 0)
333 task->GetFactory().Remove(i);
335 // if finish was removed
336 if (i == (int)task->TaskSize())
337 task->GetFactory().CheckAddFinish();
339 if (i == -1)
340 return MapTaskManager::UNMODIFIED;
342 if (!task->CheckTask())
343 return MapTaskManager::INVALID;
345 return MapTaskManager::SUCCESS;
348 MapTaskManager::TaskEditResult
349 MapTaskManager::RemoveFromTask(const Waypoint &wp)
351 assert(protected_task_manager != NULL);
352 ProtectedTaskManager::ExclusiveLease task_manager(*protected_task_manager);
353 OrderedTask *task = task_manager->Clone(GetTaskBehaviour());
355 TaskEditResult result = RemoveFromTask(task, wp);
356 if (result == SUCCESS)
357 task_manager->Commit(*task);
359 delete task;
360 return result;