void ProtectedRoutePlanner::SetTerrain(const RasterTerrain *terrain) { ExclusiveLease lease(*this); lease->set_terrain(terrain); }
void ProtectedMarkers::Reset() { ExclusiveLease lease(*this); lease->Reset(); }
/** * "Boots" up XCSoar * @param hInstance Instance handle * @param lpCmdLine Command line string * @return True if bootup successful, False otherwise */ bool XCSoarInterface::Startup() { VerboseOperationEnvironment operation; // Set the application title to "XCSoar" TCHAR szTitle[] = _T("XCSoar"); //If "XCSoar" is already running, stop this instance if (MainWindow::find(szTitle)) return false; LogStartUp(_T("Display dpi=%u,%u"), Display::GetXDPI(), Display::GetYDPI()); // Creates the main window LogStartUp(_T("Create main window")); TopWindowStyle style; if (CommandLine::full_screen) style.FullScreen(); if (CommandLine::resizable) style.Resizable(); main_window.Set(szTitle, SystemWindowSize(), style); if (!main_window.IsDefined()) return false; main_window.Initialise(); #ifdef SIMULATOR_AVAILABLE // prompt for simulator if not set by command line argument "-simulator" or "-fly" if (!sim_set_in_cmd_line_flag) { DialogLook white_look; white_look.Initialise(Fonts::map_bold, Fonts::map, Fonts::map_label, Fonts::map_bold, Fonts::map_bold); white_look.SetBackgroundColor(COLOR_WHITE); SetXMLDialogLook(white_look); SimulatorPromptResult result = dlgSimulatorPromptShowModal(); switch (result) { case SPR_QUIT: return false; case SPR_FLY: global_simulator_flag = false; break; case SPR_SIMULATOR: global_simulator_flag = true; break; } } #endif SetXMLDialogLook(main_window.GetLook().dialog); SetSystemSettings().SetDefaults(); SetComputerSettings().SetDefaults(); SetUISettings().SetDefaults(); SetUIState().Clear(); if (!LoadProfile()) return false; operation.SetText(_("Initialising")); /* create XCSoarData on the first start */ CreateDataPath(); Display::LoadOrientation(operation); main_window.InitialiseConfigured(); TCHAR path[MAX_PATH]; LocalPath(path, _T("cache")); file_cache = new FileCache(path); ReadLanguageFile(); status_messages.LoadFile(); InputEvents::readFile(); // Initialize DeviceBlackboard device_blackboard = new DeviceBlackboard(); DeviceListInitialise(); // Initialize Markers marks = new Markers(); protected_marks = new ProtectedMarkers(*marks); #ifdef HAVE_AYGSHELL_DLL const AYGShellDLL &ayg = main_window.ayg_shell_dll; ayg.SHSetAppKeyWndAssoc(VK_APP1, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP2, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP3, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP4, main_window); // Typical Record Button // Why you can't always get this to work // http://forums.devbuzz.com/m_1185/mpage_1/key_/tm.htm // To do with the fact it is a global hotkey, but you can with code above // Also APPA is record key on some systems ayg.SHSetAppKeyWndAssoc(VK_APP5, main_window); ayg.SHSetAppKeyWndAssoc(VK_APP6, main_window); #endif // Initialize main blackboard data task_manager = new TaskManager(way_points); task_manager->SetTaskEvents(task_events); task_manager->Reset(); protected_task_manager = new ProtectedTaskManager(*task_manager, XCSoarInterface::GetComputerSettings().task); // Read the terrain file operation.SetText(_("Loading Terrain File...")); LogStartUp(_T("OpenTerrain")); terrain = RasterTerrain::OpenTerrain(file_cache, operation); glide_computer = new GlideComputer(way_points, airspace_database, *protected_task_manager, task_events); glide_computer->ReadComputerSettings(GetComputerSettings()); glide_computer->SetTerrain(terrain); glide_computer->SetLogger(&logger); glide_computer->Initialise(); replay = new Replay(&logger, *protected_task_manager); // Load the EGM96 geoid data EGM96::Load(); GlidePolar &gp = SetComputerSettings().polar.glide_polar_task; gp = GlidePolar(fixed_zero); gp.SetMC(GetComputerSettings().task.safety_mc); gp.SetBugs(GetComputerSettings().polar.degradation_factor); PlaneGlue::FromProfile(SetComputerSettings().plane); PlaneGlue::Synchronize(GetComputerSettings().plane, SetComputerSettings(), gp); task_manager->SetGlidePolar(gp); // Read the topography file(s) topography = new TopographyStore(); LoadConfiguredTopography(*topography, operation); // Read the waypoint files WaypointGlue::LoadWaypoints(way_points, terrain, operation); // Read and parse the airfield info file WaypointDetails::ReadFileFromProfile(way_points, operation); // Set the home waypoint WaypointGlue::SetHome(way_points, terrain, SetComputerSettings(), device_blackboard, false); // ReSynchronise the blackboards here since SetHome touches them device_blackboard->Merge(); ReadBlackboardBasic(device_blackboard->Basic()); // Scan for weather forecast LogStartUp(_T("RASP load")); RASP.ScanAll(Basic().location, operation); // Reads the airspace files ReadAirspace(airspace_database, terrain, GetComputerSettings().pressure, operation); { const AircraftState aircraft_state = ToAircraftState(device_blackboard->Basic(), device_blackboard->Calculated()); ProtectedAirspaceWarningManager::ExclusiveLease lease(glide_computer->GetAirspaceWarnings()); lease->Reset(aircraft_state); lease->SetConfig(CommonInterface::GetComputerSettings().airspace.warnings); } #ifdef HAVE_NET noaa_store = new NOAAStore(); noaa_store->LoadFromProfile(); #endif #ifndef DISABLEAUDIOVARIO /* VarioSound_Init(); VarioSound_EnableSound(EnableSoundVario); VarioSound_SetVdead(SoundDeadband); VarioSound_SetV(0); VarioSound_SetSoundVolume(SoundVolume); */ #endif // Start the device thread(s) operation.SetText(_("Starting devices")); devStartup(); /* -- Reset polar in case devices need the data LogStartUp(_T("GlidePolar::UpdatePolar")); GlidePolar::UpdatePolar(true, GetComputerSettings()); This should be done inside devStartup if it is really required */ operation.SetText(_("Initialising display")); GlueMapWindow *map_window = main_window.GetMap(); if (map_window != NULL) { map_window->SetWaypoints(&way_points); map_window->SetTask(protected_task_manager); map_window->SetRoutePlanner(&glide_computer->GetProtectedRoutePlanner()); map_window->SetGlideComputer(glide_computer); map_window->SetAirspaces(&airspace_database); map_window->SetTopography(topography); map_window->SetTerrain(terrain); map_window->SetWeather(&RASP); map_window->SetMarks(protected_marks); map_window->SetLogger(&logger); /* show map at home waypoint until GPS fix becomes available */ if (GetComputerSettings().poi.home_location_available) map_window->SetLocation(GetComputerSettings().poi.home_location); } // Finally ready to go.. all structures must be present before this. // Create the drawing thread #ifndef ENABLE_OPENGL LogStartUp(_T("CreateDrawingThread")); draw_thread = new DrawThread(*map_window); draw_thread->Start(true); #endif // Show the infoboxes LogStartUp(_T("ShowInfoBoxes")); InfoBoxManager::Show(); // Create the calculation thread LogStartUp(_T("CreateCalculationThread")); CreateCalculationThread(); // Find unique ID of this PDA ReadAssetNumber(); glide_computer_events.Reset(); GetLiveBlackboard().AddListener(glide_computer_events); if (CommonInterface::GetComputerSettings().logger.enable_flight_logger) { flight_logger = new GlueFlightLogger(GetLiveBlackboard()); LocalPath(path, _T("flights.log")); flight_logger->SetPath(path); } LogStartUp(_T("ProgramStarted")); // Give focus to the map main_window.SetDefaultFocus(); Pages::Initialise(GetUISettings().pages); // Start calculation thread merge_thread->Start(); calculation_thread->Start(); #ifdef HAVE_TRACKING tracking = new TrackingGlue(); tracking->SetSettings(GetComputerSettings().tracking); #endif globalRunningEvent.Signal(); AfterStartup(); operation.Hide(); main_window.ResumeThreads(); return true; }
TaskManager::TaskMode ProtectedTaskManager::GetMode() const { Lease lease(*this); return lease->GetMode(); }
bool ProtectedTaskManager::TargetLock(const unsigned index, bool do_lock) { ExclusiveLease lease(*this); return lease->TargetLock(index, do_lock); }
bool ProtectedTaskManager::TaskCommit(const OrderedTask& that) { ExclusiveLease lease(*this); return lease->Commit(that); }
ProtectedTaskManager::~ProtectedTaskManager() { ExclusiveLease lease(*this); lease->SetIntersectionTest(NULL); // de-register }
/** * "Boots" up XCSoar * @param hInstance Instance handle * @param lpCmdLine Command line string * @return True if bootup successful, False otherwise */ bool Startup() { VerboseOperationEnvironment operation; #ifdef HAVE_DOWNLOAD_MANAGER Net::DownloadManager::Initialise(); #endif LogFormat("Display dpi=%u,%u", Display::GetXDPI(), Display::GetYDPI()); // Creates the main window TopWindowStyle style; if (CommandLine::full_screen) style.FullScreen(); style.Resizable(); MainWindow *const main_window = CommonInterface::main_window = new MainWindow(); main_window->Create(SystemWindowSize(), style); if (!main_window->IsDefined()) return false; #ifdef ENABLE_OPENGL LogFormat("OpenGL: " #ifdef ANDROID #ifdef USE_EGL "egl=native " #else "egl=no " #endif #endif #ifdef HAVE_OES_DRAW_TEXTURE "oesdt=%d " #endif #ifdef HAVE_DYNAMIC_MULTI_DRAW_ARRAYS "mda=%d " #endif "npot=%d vbo=%d fbo=%d stencil=%#x", #ifdef HAVE_OES_DRAW_TEXTURE OpenGL::oes_draw_texture, #endif #ifdef HAVE_DYNAMIC_MULTI_DRAW_ARRAYS GLExt::HaveMultiDrawElements(), #endif OpenGL::texture_non_power_of_two, OpenGL::vertex_buffer_object, OpenGL::frame_buffer_object, OpenGL::render_buffer_stencil); #endif CommonInterface::SetUISettings().SetDefaults(); main_window->Initialise(); #ifdef SIMULATOR_AVAILABLE // prompt for simulator if not set by command line argument "-simulator" or "-fly" if (!sim_set_in_cmd_line_flag) { SimulatorPromptResult result = dlgSimulatorPromptShowModal(); switch (result) { case SPR_QUIT: return false; case SPR_FLY: global_simulator_flag = false; break; case SPR_SIMULATOR: global_simulator_flag = true; break; } } #endif CommonInterface::SetSystemSettings().SetDefaults(); CommonInterface::SetComputerSettings().SetDefaults(); CommonInterface::SetUIState().Clear(); const auto &computer_settings = CommonInterface::GetComputerSettings(); const auto &ui_settings = CommonInterface::GetUISettings(); auto &live_blackboard = CommonInterface::GetLiveBlackboard(); if (!LoadProfile()) return false; operation.SetText(_("Initialising")); /* create XCSoarData on the first start */ CreateDataPath(); Display::LoadOrientation(operation); main_window->CheckResize(); main_window->InitialiseConfigured(); { file_cache = new FileCache(LocalPath(_T("cache"))); } ReadLanguageFile(); InputEvents::readFile(); // Initialize DeviceBlackboard device_blackboard = new DeviceBlackboard(); devices = new MultipleDevices(*asio_thread); device_blackboard->SetDevices(*devices); // Initialize main blackboard data task_events = new GlideComputerTaskEvents(); task_manager = new TaskManager(computer_settings.task, way_points); task_manager->SetTaskEvents(*task_events); task_manager->Reset(); protected_task_manager = new ProtectedTaskManager(*task_manager, computer_settings.task); // Read the terrain file operation.SetText(_("Loading Terrain File...")); LogFormat("OpenTerrain"); terrain = RasterTerrain::OpenTerrain(file_cache, operation); logger = new Logger(); glide_computer = new GlideComputer(way_points, airspace_database, *protected_task_manager, *task_events); glide_computer->ReadComputerSettings(computer_settings); glide_computer->SetTerrain(terrain); glide_computer->SetLogger(logger); glide_computer->Initialise(); replay = new Replay(logger, *protected_task_manager); #ifdef HAVE_CMDLINE_REPLAY if (CommandLine::replay_path != nullptr) { Error error; if (!replay->Start(Path(CommandLine::replay_path), error)) LogError(error); } #endif GlidePolar &gp = CommonInterface::SetComputerSettings().polar.glide_polar_task; gp = GlidePolar(0); gp.SetMC(computer_settings.task.safety_mc); gp.SetBugs(computer_settings.polar.degradation_factor); PlaneGlue::FromProfile(CommonInterface::SetComputerSettings().plane, Profile::map); PlaneGlue::Synchronize(computer_settings.plane, CommonInterface::SetComputerSettings(), gp); task_manager->SetGlidePolar(gp); // Read the topography file(s) topography = new TopographyStore(); LoadConfiguredTopography(*topography, operation); // Read the waypoint files WaypointGlue::LoadWaypoints(way_points, terrain, operation); // Read and parse the airfield info file WaypointDetails::ReadFileFromProfile(way_points, operation); // Set the home waypoint WaypointGlue::SetHome(way_points, terrain, CommonInterface::SetComputerSettings().poi, CommonInterface::SetComputerSettings().team_code, device_blackboard, false); // ReSynchronise the blackboards here since SetHome touches them device_blackboard->Merge(); CommonInterface::ReadBlackboardBasic(device_blackboard->Basic()); // Scan for weather forecast LogFormat("RASP load"); auto rasp = std::make_shared<RaspStore>(LocalPath(_T(RASP_FILENAME))); rasp->ScanAll(); // Reads the airspace files ReadAirspace(airspace_database, terrain, computer_settings.pressure, operation); { const AircraftState aircraft_state = ToAircraftState(device_blackboard->Basic(), device_blackboard->Calculated()); ProtectedAirspaceWarningManager::ExclusiveLease lease(glide_computer->GetAirspaceWarnings()); lease->Reset(aircraft_state); } #ifdef HAVE_NOAA noaa_store = new NOAAStore(); noaa_store->LoadFromProfile(); #endif AudioVarioGlue::Initialise(); AudioVarioGlue::Configure(ui_settings.sound.vario); // Start the device thread(s) operation.SetText(_("Starting devices")); devStartup(); /* -- Reset polar in case devices need the data GlidePolar::UpdatePolar(true, computer_settings); This should be done inside devStartup if it is really required */ operation.SetText(_("Initialising display")); GlueMapWindow *map_window = main_window->GetMap(); if (map_window != nullptr) { map_window->SetWaypoints(&way_points); map_window->SetTask(protected_task_manager); map_window->SetRoutePlanner(&glide_computer->GetProtectedRoutePlanner()); map_window->SetGlideComputer(glide_computer); map_window->SetAirspaces(&airspace_database); map_window->SetTopography(topography); map_window->SetTerrain(terrain); map_window->SetRasp(rasp); #ifdef HAVE_NOAA map_window->SetNOAAStore(noaa_store); #endif /* show map at home waypoint until GPS fix becomes available */ if (computer_settings.poi.home_location_available) map_window->SetLocation(computer_settings.poi.home_location); } // Finally ready to go.. all structures must be present before this. // Create the drawing thread #ifndef ENABLE_OPENGL draw_thread = new DrawThread(*map_window); draw_thread->Start(true); #endif // Show the infoboxes InfoBoxManager::Show(); // Create the calculation thread CreateCalculationThread(); // Find unique ID of this PDA ReadAssetNumber(); glide_computer_events = new GlideComputerEvents(); glide_computer_events->Reset(); live_blackboard.AddListener(*glide_computer_events); all_monitors = new AllMonitors(); if (!is_simulator() && computer_settings.logger.enable_flight_logger) { flight_logger = new GlueFlightLogger(live_blackboard); flight_logger->SetPath(LocalPath(_T("flights.log"))); } if (computer_settings.logger.enable_nmea_logger) NMEALogger::enabled = true; LogFormat("ProgramStarted"); // Give focus to the map main_window->SetDefaultFocus(); // Start calculation thread merge_thread->Start(); calculation_thread->Start(); PageActions::Update(); #ifdef HAVE_TRACKING tracking = new TrackingGlue(*asio_thread); tracking->SetSettings(computer_settings.tracking); #ifdef HAVE_SKYLINES_TRACKING if (map_window != nullptr) map_window->SetSkyLinesData(&tracking->GetSkyLinesData()); #endif #endif assert(!global_running); global_running = true; AfterStartup(); operation.Hide(); main_window->FinishStartup(); return true; }
void ProtectedAirspaceWarningManager::Clear() { ExclusiveLease lease(*this); lease->clear(); }
/** * Refreshes UI based on location of target and current task stats */ static void RefreshCalculator() { bool nodisplay = false; bool is_aat; fixed aat_time; { ProtectedTaskManager::Lease lease(*protected_task_manager); const OrderedTask &task = lease->GetOrderedTask(); const AATPoint *ap = task.GetAATTaskPoint(target_point); is_aat = ap != nullptr; if (!is_aat || target_point < initial_active_task_point) { nodisplay = true; is_locked = false; } else { range_and_radial = ap->GetTargetRangeRadial(range_and_radial.range); is_locked = ap->IsTargetLocked(); } aat_time = task.GetOrderedTaskSettings().aat_min_time; } if (optimized_checkbox) { optimized_checkbox->SetVisible(is_aat); optimized_checkbox->SetState(!is_locked); } LockCalculatorUI(); ShowOptionalFormControl(*wf, _T("prpRange"), !nodisplay); ShowOptionalFormControl(*wf, _T("prpRadial"), !nodisplay); if (!nodisplay) LoadRangeAndRadial(); // update outputs const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; const fixed aat_time_estimated = task_stats.GetEstimatedTotalTime(); ShowOptionalFormControl(*wf, _T("prpAATEst"), !nodisplay); ShowFormControl(*wf, _T("prpAATDelta"), !nodisplay); if (!nodisplay) { LoadOptionalFormProperty(*wf, _T("prpAATEst"), aat_time_estimated / fixed(60)); LoadFormProperty(*wf, _T("prpAATDelta"), (aat_time_estimated - aat_time) / 60); } const ElementStat &total = task_stats.total; if (total.remaining_effective.IsDefined()) LoadFormProperty(*wf, _T("prpSpeedRemaining"), UnitGroup::TASK_SPEED, total.remaining_effective.GetSpeed()); if (total.travelled.IsDefined()) LoadOptionalFormProperty(*wf, _T("prpSpeedAchieved"), UnitGroup::TASK_SPEED, total.travelled.GetSpeed()); }
void Update() { ProtectedTaskManager::Lease lease(*protected_task_manager); alternates = lease->GetAlternates(); }
static void OnAirspaceListItemPaint(Canvas &canvas, const RECT paint_rc, unsigned i) { TCHAR sTmp[128]; ProtectedAirspaceWarningManager::Lease lease(airspace_warnings); if (lease->empty()) { assert(i == 0); canvas.text(paint_rc.left + IBLSCALE(2), paint_rc.top + IBLSCALE(2), _("No Warnings")); return; } assert(i < lease->size()); const AirspaceWarning* _warning = lease->get_warning(i); const AirspaceWarning warning = *_warning; const AbstractAirspace& as = warning.get_airspace(); const AirspaceInterceptSolution& solution = warning.get_solution(); tstring sName = as.get_name_text(false); tstring sTop = as.get_top_text(true); tstring sBase = as.get_base_text(true); tstring sType = as.get_type_text(true); const int TextHeight = 12, TextTop = 1; const int Col0Left = 3, Col1Left = 120, Col2Left = 200; RECT rcTextClip; rcTextClip = paint_rc; rcTextClip.right = IBLSCALE(Col1Left - 2); Color old_text_color = canvas.get_text_color(); if (!warning.get_ack_expired()) canvas.set_text_color(Color::GRAY); { // name, altitude info _stprintf(sTmp, _T("%-20s"), sName.c_str()); canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left), paint_rc.top + IBLSCALE(TextTop), rcTextClip, sTmp); _stprintf(sTmp, _T("%-20s"), sTop.c_str()); canvas.text(paint_rc.left + IBLSCALE(Col1Left), paint_rc.top + IBLSCALE(TextTop), sTmp); _stprintf(sTmp, _T("%-20s"), sBase.c_str()); canvas.text(paint_rc.left + IBLSCALE(Col1Left), paint_rc.top + IBLSCALE(TextTop + TextHeight), sTmp); } if (warning.get_warning_state() != AirspaceWarning::WARNING_INSIDE && warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) { _stprintf(sTmp, _T("%d secs dist %d m"), (int)solution.elapsed_time, (int)solution.distance); canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left), paint_rc.top + IBLSCALE(TextTop + TextHeight), rcTextClip, sTmp); } /* draw the warning state indicator */ Brush *state_brush; const TCHAR *state_text; if (warning.get_warning_state() == AirspaceWarning::WARNING_INSIDE) { if (warning.get_ack_expired()) state_brush = &hBrushInsideBk; else state_brush = &hBrushInsideAckBk; state_text = _T("inside"); } else if (warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) { if (warning.get_ack_expired()) state_brush = &hBrushNearBk; else state_brush = &hBrushNearAckBk; state_text = _T("near"); } else { state_brush = NULL; state_text = NULL; } const SIZE state_text_size = canvas.text_size(state_text != NULL ? state_text : _T("W")); if (state_brush != NULL) { /* colored background */ RECT rc; rc.left = paint_rc.left + Layout::FastScale(Col2Left); rc.top = paint_rc.top + Layout::FastScale(2); rc.right = rc.left + state_text_size.cx + Layout::FastScale(4); rc.bottom = paint_rc.bottom - Layout::FastScale(2); canvas.fill_rectangle(rc, *state_brush); } if (state_text != NULL) canvas.text(paint_rc.left + Layout::FastScale(Col2Left + 2), (paint_rc.bottom + paint_rc.top - state_text_size.cy) / 2, state_text); /* TCHAR sAckIndicator[6] = _T(" -++*"); if (pAS.Inside){ _stprintf(sTmp, _T("> %c %s"), sAckIndicator[pAS.Acknowledge], sType); } else { TCHAR DistanceText[MAX_PATH]; if (pAS.hDistance == 0) { // Directly above or below airspace Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7); if (pAS.vDistance > 0) { _stprintf(sTmp, _T("< %c %s ab %s"), sAckIndicator[pAS.Acknowledge], sType, DistanceText); } if (pAS.vDistance < 0) { Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7); _stprintf(sTmp, _T("< %c %s bl %s"), sAckIndicator[pAS.Acknowledge], sType, DistanceText); } } else { if ((pAS.vDistance == 0) || (pAS.hDistance < abs(pAS.vDistance)*30 )) { // Close to airspace altitude, horizontally separated Units::FormatUserDistance(fabs((double)pAS.hDistance),DistanceText, 7); _stprintf(sTmp, _T("< %c %s H %s"), sAckIndicator[pAS.Acknowledge], sType, DistanceText); } else { // Effectively above or below airspace, steep climb or descent // necessary to enter Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7); if (pAS.vDistance > 0) { _stprintf(sTmp, _T("< %c %s ab %s"), sAckIndicator[pAS.Acknowledge], sType, DistanceText); } else { _stprintf(sTmp, _T("< %c %s bl %s"), sAckIndicator[pAS.Acknowledge], sType, DistanceText); } } } } canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left), paint_rc.top + IBLSCALE(TextTop + TextHeight), rcTextClip, sTmp); */ if (!warning.get_ack_expired()) canvas.set_text_color(old_text_color); }
bool Update() { ProtectedTaskManager::Lease lease(*protected_task_manager); alternates = lease->GetAlternates(); return !alternates.empty(); }
/** * "Boots" up XCSoar * @param hInstance Instance handle * @param lpCmdLine Command line string * @return True if bootup successful, False otherwise */ bool Startup() { VerboseOperationEnvironment operation; #ifdef USE_GDI //If "XCSoar" is already running, stop this instance if (MainWindow::Find()) return false; #endif #ifdef HAVE_DOWNLOAD_MANAGER Net::DownloadManager::Initialise(); #endif LogFormat("Display dpi=%u,%u", Display::GetXDPI(), Display::GetYDPI()); // Creates the main window TopWindowStyle style; if (CommandLine::full_screen) style.FullScreen(); style.Resizable(); MainWindow *const main_window = CommonInterface::main_window = new MainWindow(CommonInterface::status_messages); main_window->Create(SystemWindowSize(), style); if (!main_window->IsDefined()) return false; #ifdef ENABLE_OPENGL LogFormat("OpenGL: " #ifdef HAVE_DYNAMIC_EGL "egl=%d " #endif "npot=%d vbo=%d fbo=%d stencil=%#x", #ifdef HAVE_DYNAMIC_EGL OpenGL::egl, #endif OpenGL::texture_non_power_of_two, OpenGL::vertex_buffer_object, OpenGL::frame_buffer_object, OpenGL::render_buffer_stencil); #endif main_window->Initialise(); #ifdef SIMULATOR_AVAILABLE // prompt for simulator if not set by command line argument "-simulator" or "-fly" if (!sim_set_in_cmd_line_flag) { DialogLook white_look; white_look.Initialise(Fonts::map_bold, Fonts::map, Fonts::map_label, Fonts::map_bold, Fonts::map_bold, Fonts::map_bold); white_look.SetBackgroundColor(COLOR_WHITE); SetXMLDialogLook(white_look); SimulatorPromptResult result = dlgSimulatorPromptShowModal(); switch (result) { case SPR_QUIT: return false; case SPR_FLY: global_simulator_flag = false; break; case SPR_SIMULATOR: global_simulator_flag = true; break; } } #endif SetXMLDialogLook(main_window->GetLook().dialog); CommonInterface::SetSystemSettings().SetDefaults(); CommonInterface::SetComputerSettings().SetDefaults(); CommonInterface::SetUISettings().SetDefaults(); CommonInterface::SetUIState().Clear(); const auto &computer_settings = CommonInterface::GetComputerSettings(); const auto &ui_settings = CommonInterface::GetUISettings(); auto &live_blackboard = CommonInterface::GetLiveBlackboard(); if (!LoadProfile()) return false; operation.SetText(_("Initialising")); /* create XCSoarData on the first start */ CreateDataPath(); Display::LoadOrientation(operation); main_window->CheckResize(); main_window->InitialiseConfigured(); TCHAR path[MAX_PATH]; LocalPath(path, _T("cache")); file_cache = new FileCache(path); ReadLanguageFile(); CommonInterface::status_messages.LoadFile(); InputEvents::readFile(); // Initialize DeviceBlackboard device_blackboard = new DeviceBlackboard(); DeviceListInitialise(); // Initialize Markers marks = new Markers(); protected_marks = new ProtectedMarkers(*marks); #ifdef HAVE_AYGSHELL_DLL const AYGShellDLL &ayg = main_window->ayg_shell_dll; ayg.SHSetAppKeyWndAssoc(VK_APP1, *main_window); ayg.SHSetAppKeyWndAssoc(VK_APP2, *main_window); ayg.SHSetAppKeyWndAssoc(VK_APP3, *main_window); ayg.SHSetAppKeyWndAssoc(VK_APP4, *main_window); // Typical Record Button // Why you can't always get this to work // http://forums.devbuzz.com/m_1185/mpage_1/key_/tm.htm // To do with the fact it is a global hotkey, but you can with code above // Also APPA is record key on some systems ayg.SHSetAppKeyWndAssoc(VK_APP5, *main_window); ayg.SHSetAppKeyWndAssoc(VK_APP6, *main_window); #endif // Initialize main blackboard data task_events = new GlideComputerTaskEvents(); task_manager = new TaskManager(computer_settings.task, way_points); task_manager->SetTaskEvents(*task_events); task_manager->Reset(); protected_task_manager = new ProtectedTaskManager(*task_manager, computer_settings.task); // Read the terrain file operation.SetText(_("Loading Terrain File...")); LogFormat("OpenTerrain"); terrain = RasterTerrain::OpenTerrain(file_cache, operation); logger = new Logger(); glide_computer = new GlideComputer(way_points, airspace_database, *protected_task_manager, *task_events); glide_computer->ReadComputerSettings(computer_settings); glide_computer->SetTerrain(terrain); glide_computer->SetLogger(logger); glide_computer->Initialise(); replay = new Replay(logger, *protected_task_manager); // Load the EGM96 geoid data EGM96::Load(); GlidePolar &gp = CommonInterface::SetComputerSettings().polar.glide_polar_task; gp = GlidePolar(fixed(0)); gp.SetMC(computer_settings.task.safety_mc); gp.SetBugs(computer_settings.polar.degradation_factor); PlaneGlue::FromProfile(CommonInterface::SetComputerSettings().plane); PlaneGlue::Synchronize(computer_settings.plane, CommonInterface::SetComputerSettings(), gp); task_manager->SetGlidePolar(gp); // Read the topography file(s) topography = new TopographyStore(); LoadConfiguredTopography(*topography, operation); // Read the waypoint files WaypointGlue::LoadWaypoints(way_points, terrain, operation); // Read and parse the airfield info file WaypointDetails::ReadFileFromProfile(way_points, operation); // Set the home waypoint WaypointGlue::SetHome(way_points, terrain, CommonInterface::SetComputerSettings().poi, CommonInterface::SetComputerSettings().team_code, device_blackboard, false); // ReSynchronise the blackboards here since SetHome touches them device_blackboard->Merge(); CommonInterface::ReadBlackboardBasic(device_blackboard->Basic()); // Scan for weather forecast LogFormat("RASP load"); RASP.ScanAll(CommonInterface::Basic().location, operation); // Reads the airspace files ReadAirspace(airspace_database, terrain, computer_settings.pressure, operation); { const AircraftState aircraft_state = ToAircraftState(device_blackboard->Basic(), device_blackboard->Calculated()); ProtectedAirspaceWarningManager::ExclusiveLease lease(glide_computer->GetAirspaceWarnings()); lease->Reset(aircraft_state); } #ifdef HAVE_NOAA noaa_store = new NOAAStore(); noaa_store->LoadFromProfile(); #endif AudioVarioGlue::Initialise(); AudioVarioGlue::Configure(ui_settings.sound.vario); // Start the device thread(s) operation.SetText(_("Starting devices")); devStartup(); /* -- Reset polar in case devices need the data GlidePolar::UpdatePolar(true, computer_settings); This should be done inside devStartup if it is really required */ operation.SetText(_("Initialising display")); GlueMapWindow *map_window = main_window->GetMap(); if (map_window != NULL) { map_window->SetWaypoints(&way_points); map_window->SetTask(protected_task_manager); map_window->SetRoutePlanner(&glide_computer->GetProtectedRoutePlanner()); map_window->SetGlideComputer(glide_computer); map_window->SetAirspaces(&airspace_database); map_window->SetTopography(topography); map_window->SetTerrain(terrain); map_window->SetWeather(&RASP); map_window->SetMarks(protected_marks); map_window->SetLogger(logger); #ifdef HAVE_NOAA map_window->SetNOAAStore(noaa_store); #endif /* show map at home waypoint until GPS fix becomes available */ if (computer_settings.poi.home_location_available) map_window->SetLocation(computer_settings.poi.home_location); } // Finally ready to go.. all structures must be present before this. // Create the drawing thread #ifndef ENABLE_OPENGL draw_thread = new DrawThread(*map_window); draw_thread->Start(true); #endif // Show the infoboxes InfoBoxManager::Show(); // Create the calculation thread CreateCalculationThread(); // Find unique ID of this PDA ReadAssetNumber(); glide_computer_events = new GlideComputerEvents(); glide_computer_events->Reset(); live_blackboard.AddListener(*glide_computer_events); all_monitors = new AllMonitors(); if (computer_settings.logger.enable_flight_logger) { flight_logger = new GlueFlightLogger(live_blackboard); LocalPath(path, _T("flights.log")); flight_logger->SetPath(path); } if (computer_settings.logger.enable_nmea_logger) NMEALogger::enabled = true; LogFormat("ProgramStarted"); // Give focus to the map main_window->SetDefaultFocus(); // Start calculation thread merge_thread->Start(); calculation_thread->Start(); PageActions::Update(); #ifdef HAVE_TRACKING tracking = new TrackingGlue(); tracking->SetSettings(computer_settings.tracking); #ifdef HAVE_SKYLINES_TRACKING_HANDLER if (map_window != nullptr) map_window->SetSkyLinesData(&tracking->GetSkyLinesData()); #endif #endif assert(!global_running); global_running = true; AfterStartup(); operation.Hide(); main_window->FinishStartup(); return true; }
fixed ProtectedTaskManager::GetFinishHeight() const { Lease lease(*this); return lease->GetFinishHeight(); }
void ProtectedAirspaceWarningManager::AcknowledgeAll() { ExclusiveLease lease(*this); lease->AcknowledgeAll(); }
OrderedTask* ProtectedTaskManager::TaskClone() const { Lease lease(*this); return lease->Clone(task_behaviour); }
bool ProtectedAirspaceWarningManager::IsEmpty() const { Lease lease(*this); return lease->empty(); }
void ProtectedTaskManager::Reset() { ExclusiveLease lease(*this); lease->Reset(); }
bool ProtectedAirspaceWarningManager::GetAckDay(const AbstractAirspace &airspace) const { Lease lease(*this); return lease->GetAckDay(airspace); }
void ProtectedTaskManager::SetGlidePolar(const GlidePolar &glide_polar) { ExclusiveLease lease(*this); lease->SetGlidePolar(glide_polar); }
const OrderedTaskSettings ProtectedTaskManager::GetOrderedTaskSettings() const { Lease lease(*this); return lease->GetOrderedTask().GetOrderedTaskSettings(); }
const OrderedTaskBehaviour ProtectedTaskManager::GetOrderedTaskBehaviour() const { Lease lease(*this); return lease->GetOrderedTaskBehaviour(); }
void ProtectedTaskManager::IncrementActiveTaskPoint(int offset) { ExclusiveLease lease(*this); lease->IncrementActiveTaskPoint(offset); }
static void OnAirspaceListItemPaint(Canvas &canvas, const PixelRect paint_rc, unsigned i) { TCHAR sTmp[128]; const int paint_rc_margin = 2; ///< This constant defines the margin that should be respected for renderring within the paint_rc area. bool ack1_vis; bool ack2_vis; bool ack_vis; bool enable_vis; bool update_vis = false; { ProtectedAirspaceWarningManager::Lease lease(*airspace_warnings); if (lease->empty()) { // the warnings were emptied between the opening of the dialog // and this refresh, so only need to display "No Warnings" for // top item, otherwise exit immediately if (i==0) { canvas.text(paint_rc.left + IBLSCALE(paint_rc_margin), paint_rc.top + IBLSCALE(paint_rc_margin), _("No Warnings")); } return; } if (i >= lease->size()) /* this cannot be an assertion, because another thread may have modified the AirspaceWarningManager */ return; const AirspaceWarning warning = *(lease->get_warning(i)); const AbstractAirspace& as = warning.get_airspace(); const AirspaceInterceptSolution& solution = warning.get_solution(); tstring sName = as.get_name_text(false); tstring sTop = as.get_top_text(true); tstring sBase = as.get_base_text(true); tstring sType = as.get_type_text(true); const int TextHeight = 12, TextTop = 1; const int statusColWidth = canvas.text_width(_T("inside")); //<-- word "inside" is used as the etalon, because it is longer than "near" and currently (9.4.2011) there is no other possibility for the status text. const int heightColWidth = canvas.text_width(_T("1888 m AGL")); // <-- "1888" is used in order to have enough space for 4-digit heights with "AGL" /// Dynamic columns scaling - "name" column is flexible, altitude and state columns are fixed-width. const int Col0LeftScreenCoords = Layout::FastScale(paint_rc_margin), Col2LeftScreenCoords = paint_rc.right - Layout::FastScale(paint_rc_margin) - (statusColWidth + 2 * Layout::FastScale(paint_rc_margin)), Col1LeftScreenCoords = Col2LeftScreenCoords - Layout::FastScale(paint_rc_margin) - heightColWidth; PixelRect rcTextClip; rcTextClip = paint_rc; rcTextClip.right = Col1LeftScreenCoords - Layout::FastScale(paint_rc_margin); Color old_text_color = canvas.get_text_color(); if (!warning.get_ack_expired()) canvas.set_text_color(COLOR_GRAY); { // name, altitude info _stprintf(sTmp, _T("%-20s"), sName.c_str()); canvas.text_clipped(paint_rc.left + Col0LeftScreenCoords, paint_rc.top + IBLSCALE(TextTop), rcTextClip, sTmp); _stprintf(sTmp, _T("%-20s"), sTop.c_str()); canvas.text(paint_rc.left + Col1LeftScreenCoords, paint_rc.top + IBLSCALE(TextTop), sTmp); _stprintf(sTmp, _T("%-20s"), sBase.c_str()); canvas.text(paint_rc.left + Col1LeftScreenCoords, paint_rc.top + IBLSCALE(TextTop + TextHeight), sTmp); } if (warning.get_warning_state() != AirspaceWarning::WARNING_INSIDE && warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) { _stprintf(sTmp, _T("%d secs dist %d m"), (int)solution.elapsed_time, (int)solution.distance); canvas.text_clipped(paint_rc.left + Col0LeftScreenCoords, paint_rc.top + IBLSCALE(TextTop + TextHeight), rcTextClip, sTmp); } /* draw the warning state indicator */ Brush *state_brush; const TCHAR *state_text; if (warning.get_warning_state() == AirspaceWarning::WARNING_INSIDE) { if (warning.get_ack_expired()) state_brush = &hBrushInsideBk; else state_brush = &hBrushInsideAckBk; state_text = _T("inside"); } else if (warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) { if (warning.get_ack_expired()) state_brush = &hBrushNearBk; else state_brush = &hBrushNearAckBk; state_text = _T("near"); } else { state_brush = NULL; state_text = NULL; } const PixelSize state_text_size = canvas.text_size(state_text != NULL ? state_text : _T("W")); if (state_brush != NULL) { /* colored background */ PixelRect rc; rc.left = paint_rc.left + Col2LeftScreenCoords; rc.top = paint_rc.top + Layout::FastScale(paint_rc_margin); rc.right = paint_rc.right - Layout::FastScale(paint_rc_margin); rc.bottom = paint_rc.bottom - Layout::FastScale(paint_rc_margin); canvas.fill_rectangle(rc, *state_brush); } if (state_text != NULL) { // -- status text will be centered inside its table cell: canvas.text(paint_rc.left + Col2LeftScreenCoords + Layout::FastScale(paint_rc_margin) + (statusColWidth / 2) - (canvas.text_width(state_text) / 2), (paint_rc.bottom + paint_rc.top - state_text_size.cy) / 2, state_text); } if (!warning.get_ack_expired()) canvas.set_text_color(old_text_color); if (CursorAirspace == &as) { update_vis = true; if (!warning.get_ack_expired()) { ack1_vis = false; ack_vis = false; } else { if (warning.get_warning_state() == AirspaceWarning::WARNING_INSIDE) { ack_vis = true; ack1_vis = false; } else { ack_vis = false; ack1_vis = true; } } ack2_vis = !warning.get_ack_day(); enable_vis = !warning.get_ack_expired(); } } // close scope if (update_vis) { wbAck1->set_visible(ack1_vis); wbAck2->set_visible(ack2_vis); wbAck->set_visible(ack_vis); wbEnable->set_visible(enable_vis); } }
bool ProtectedTaskManager::DoGoto(const Waypoint &wp) { ExclusiveLease lease(*this); return lease->DoGoto(wp); }
void ProtectedMarkers::MarkLocation(const GeoPoint &loc, const BrokenDateTime &time) { ExclusiveLease lease(*this); lease->MarkLocation(loc, time); }
AircraftState ProtectedTaskManager::GetStartState() const { Lease lease(*this); return lease->GetStartState(); }
void Reset() { ExclusiveLease lease(*this); lease->reset(); }
static void SettingsLeave() { if (!globalRunningEvent.test()) return; XCSoarInterface::main_window.map.set_focus(); SuspendAllThreads(); if (MapFileChanged) { AirspaceFileChanged = true; AirfieldFileChanged = true; WaypointFileChanged = true; TerrainFileChanged = true; TopologyFileChanged = true; } if ((WaypointFileChanged) || (TerrainFileChanged) || (AirfieldFileChanged)) { ProgressGlue::Create(_("Loading Terrain File...")); XCSoarInterface::main_window.map.set_terrain(NULL); // re-load terrain delete terrain; terrain = RasterTerrain::OpenTerrain(file_cache); // re-load waypoints WayPointGlue::ReadWaypoints(way_points, terrain); ReadAirfieldFile(way_points); // re-set home if (WaypointFileChanged || TerrainFileChanged) { WayPointGlue::SetHome(way_points, terrain, XCSoarInterface::SetSettingsComputer(), WaypointFileChanged, false); } if (terrain != NULL) { RasterTerrain::UnprotectedLease lease(*terrain); lease->SetViewCenter(XCSoarInterface::Basic().Location); } XCSoarInterface::main_window.map.set_terrain(terrain); } if (TopologyFileChanged) LoadConfiguredTopology(*topology); if (AirspaceFileChanged) { airspace_warnings.clear(); airspace_database.clear(); ReadAirspace(airspace_database, terrain, XCSoarInterface::Basic().pressure); } if (PolarFileChanged) { GlidePolar gp = protected_task_manager.get_glide_polar(); if (LoadPolarById(XCSoarInterface::SettingsComputer(), gp)) { protected_task_manager.set_glide_polar(gp); } } { ProtectedTaskManager::ExclusiveLease lease(protected_task_manager); lease->set_olc_rules(XCSoarInterface::SettingsComputer().olc_rules); } if (AirfieldFileChanged || AirspaceFileChanged || WaypointFileChanged || TerrainFileChanged || TopologyFileChanged) { ProgressGlue::Close(); XCSoarInterface::main_window.map.set_focus(); draw_thread->trigger_redraw(); } if (DevicePortChanged) devRestart(); ResumeAllThreads(); // allow map and calculations threads to continue }