bool TaskManager::Commit(const OrderedTask& other) { bool retval = task_ordered.Commit(other); if (other.TaskSize()) { // if valid, resume the task switch (mode) { case MODE_NULL: SetMode(MODE_ORDERED); // set mode first SetActiveTaskPoint(0); // then set tp break; case MODE_GOTO: case MODE_ABORT: // resume on load SetMode(MODE_ORDERED); break; case MODE_ORDERED: IncrementActiveTaskPoint(0); // ensure tp is within size break; }; } else if (mode == MODE_ORDERED) { SetActiveTaskPoint(0); // reset tp of ordered task so will be zero // on next load if valid SetMode(MODE_NULL); } return retval; }
void TaskManager::IncrementActiveTaskPoint(int offset) { if (active_task) { unsigned i = GetActiveTaskPointIndex(); if ((int)i+offset<0) { // prevent wrap-around if (mode == MODE_ORDERED) task_ordered.RotateOptionalStarts(); else SetActiveTaskPoint(0); } else { SetActiveTaskPoint(i+offset); } } }
void OrderedTask::Reset() { /// @todo also reset data in this class e.g. stats? ResetPoints(task_points); ResetPoints(optional_start_points); AbstractTask::Reset(); stats.task_finished = false; stats.task_started = false; task_advance.Reset(); SetActiveTaskPoint(0); }
bool OrderedTask::CheckTransitions(const AircraftState &state, const AircraftState &state_last) { if (!taskpoint_start) return false; taskpoint_start->ScanActive(*task_points[active_task_point]); if (!state.flying) return false; const int n_task = task_points.size(); if (!n_task) return false; FlatBoundingBox bb_last(task_projection.project(state_last.location),1); FlatBoundingBox bb_now(task_projection.project(state.location),1); bool last_started = TaskStarted(); const bool last_finished = TaskFinished(); const int t_min = max(0, (int)active_task_point - 1); const int t_max = min(n_task - 1, (int)active_task_point); bool full_update = false; for (int i = t_min; i <= t_max; i++) { bool transition_enter = false; bool transition_exit = false; if (i==0) { full_update |= CheckTransitionOptionalStart(state, state_last, bb_now, bb_last, transition_enter, transition_exit, last_started); } full_update |= CheckTransitionPoint(*task_points[i], state, state_last, bb_now, bb_last, transition_enter, transition_exit, last_started, i == 0); if (i == (int)active_task_point) { const bool last_request_armed = task_advance.NeedToArm(); if (task_advance.CheckReadyToAdvance(*task_points[i], state, transition_enter, transition_exit)) { task_advance.SetArmed(false); if (i + 1 < n_task) { i++; SetActiveTaskPoint(i); taskpoint_start->ScanActive(*task_points[active_task_point]); if (task_events != NULL) task_events->ActiveAdvanced(*task_points[i], i); // on sector exit, must update samples since start sector // exit transition clears samples full_update = true; } } else if (!last_request_armed && task_advance.NeedToArm()) { if (task_events != NULL) task_events->RequestArm(*task_points[i]); } } } taskpoint_start->ScanActive(*task_points[active_task_point]); stats.task_finished = TaskFinished(); stats.task_started = TaskStarted(); if (stats.task_started) taskpoint_finish->set_fai_finish_height(GetStartState().altitude - fixed(1000)); if (task_events != NULL) { if (stats.task_started && !last_started) task_events->TaskStart(); if (stats.task_finished && !last_finished) task_events->TaskFinish(); } return full_update; }