bool CRenderingDlg::StartNextJob() { while (m_CurJob < GetJobCount()) { CString s; s.Format(IDS_REND_STATUS, m_CurJob, GetJobCount(), round(m_CurJob * 100.0 / GetJobCount())); m_Status.SetWindowText(s); // update status text CSnapshot& Snap = m_Hist->GetItem(m_JobList[m_CurJob]); if (m_CurJob > 0) { // if previous item has escape times and differs from this item in // color only, share previous item's escape times, avoiding render CSnapshot& PrevSnap = m_Hist->GetItem(m_JobList[m_CurJob - 1]); if (PrevSnap.HasEscTimes() && Snap.EqualIgnoreColor(PrevSnap)) Snap.m_EscTimes = PrevSnap.m_EscTimes; // add a reference } if (Exporting()) { // if exporting bitmaps m_View->SetSnapshotCached(Snap, TRUE); // render; allow color remap } else { // not exporting if (m_SaveEscTimes && !Snap.HasEscTimes()) // if escape times needed Snap.m_Image.SetEmpty(); // delete image to force render m_View->SetSnapshotCached(Snap, TRUE); // render; allow color remap } if (!m_View->IsIdle()) // if engine is busy doing whatever return(TRUE); // engine will send us UWM_RENDERDONE when it's done // engine is idle; assume image and/or escape times were cached if (!FinishJob()) // if error finishing job return(FALSE); // abort; assume dialog is already ended } OnOK(); // no more jobs; success return(TRUE); }
void CJobControlDlg::UpdateStatuses(int OldStatus, int NewStatus) { for (int i = 0; i < GetJobCount(); i++) { if (GetStatus(i) == OldStatus) SetStatus(i, NewStatus); } }
void CJobControlDlg::Delete(int JobIdx) { m_Job.m_Info.RemoveAt(JobIdx); if (!GetJobCount()) // if queue is empty m_Job.m_NextID = 0; // reset unique ID sequence UpdateList(); }
bool CRenderingDlg::BuildJobList() { m_View = theApp.GetMain()->GetView(); if (m_View == NULL) return(FALSE); COptionsDlg& opts = theApp.GetMain()->GetOptionsDlg(); m_CacheImages = opts.GetCacheImages(); m_SaveEscTimes = opts.GetSaveEscTimes(); m_RenderCount = 0; m_Hist = m_View->GetHistoryView(); m_Hist->GetSelection(m_JobList); int jobs = GetJobCount(); for (int i = 0; i < jobs; i++) { CSnapshot& snap = m_Hist->GetItem(m_JobList[i]); if (!snap.HasImage() || (!snap.HasEscTimes() && m_SaveEscTimes)) m_RenderCount++; // count item as a render } if (!Exporting()) { // if not exporting if (!m_RenderCount) // if no items need rendering return(TRUE); // nothing to do if (!m_CacheImages) { // if not caching images // multiple render is pointless since images wouldn't be saved AfxMessageBox(IDS_REND_CANT_MULTI_RENDER); return(FALSE); } } return(TRUE); }
BOOL CRenderingDlg::OnInitDialog() { CDialog::OnInitDialog(); if (!m_Caption.IsEmpty()) SetWindowText(m_Caption); if (BuildJobList()) { // if job list builds OK if (m_RenderCount || Exporting()) { // if we have work to do m_Progress.SetRange32(0, GetJobCount()); // set progress bar range // intercept all messages sent by the view's engine; our handlers // will forward the messages to the view m_PrevEngineWnd = m_View->GetEngine().GetNotifyWnd(); m_View->GetEngine().SetNotifyWnd(m_hWnd); // we don't call StartNextJob directly, because if all the images // are cached, StartNextJob finishes all the jobs and calls OnOK // before returning, in which case we'll never have been visible; // post a message instead, and call StartNextJob from the handler PostMessage(UWM_STARTNEXTJOB); } else // job list is empty OnOK(); // nothing to do } else // error building job list EndDialog(IDABORT); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
int CJobControlDlg::FindByStatus(int Status) const { int jobs = GetJobCount(); for (int i = 0; i < jobs; i++) { if (m_Job.m_Info[i].m_Status == Status) return(i); } return(-1); }
int CJobControlDlg::FindByID(int JobID) const { int jobs = GetJobCount(); for (int i = 0; i < jobs; i++) { if (m_Job.m_Info[i].m_ID == JobID) return(i); } return(-1); }
void CJobControlDlg::Move(int Src, int Dest) { if (Src == Dest) return; // nothing to do CJobInfo info = m_Job.m_Info[Src]; m_Job.m_Info.RemoveAt(Src); m_Job.m_Info.InsertAt(min(Dest, GetJobCount()), info); SetCurSel(Dest); UpdateList(); }
void CJobControlDlg::OnDestroy() { if (GetJobCount() || m_JobFileRead) { // if we have jobs or job file was read if (!PathFileExists(m_JobPath)) { // if job file doesn't exist yet CString JobFolder; theApp.GetAppDataFolder(JobFolder); theApp.CreateFolder(JobFolder); // make sure destination folder exists } m_Job.Write(m_JobPath); // write jobs } CToolDlg::OnDestroy(); }
void CJobControlDlg::UpdateUI(int JobIdx) { int jobs = GetJobCount(); if (JobIdx < 0) JobIdx = GetCurSel(); // update job positioning buttons m_MoveUpBtn.EnableWindow(JobIdx > 0); m_MoveDownBtn.EnableWindow(JobIdx >= 0 && JobIdx < jobs - 1); // update job status buttons; don't let user change status of running job bool StatChgOK = JobIdx >= 0 && !IsRunning(JobIdx); m_PostponeBtn.EnableWindow(StatChgOK); m_DeleteBtn.EnableWindow(StatChgOK); // update job control buttons bool BatchMode = m_Main->GetBatchMode(); // true if batch jobs are running m_StartBtn.EnableWindow(jobs && !BatchMode && FindWaiting() >= 0); m_AbortBtn.EnableWindow(jobs && BatchMode); m_SkipBtn.EnableWindow(JobIdx >= 0 && BatchMode); }
void CJobControlDlg::UpdateList() { m_List.SetItemCountEx(GetJobCount(), 0); // invalidate all items UpdateUI(); }
void glTextureManager::BuildCompressedCache() { idx_sorted_by_distance.Clear(); // Building the cache may take a long time.... // Be a little smarter. // Build a sorted array of chart database indices, sorted on distance from the ownship currently. // This way, a user may build a few charts textures for immediate use, then "skip" out on the rest until later. int count = 0; for(int i = 0; i<ChartData->GetChartTableEntries(); i++) { /* skip if not kap */ const ChartTableEntry &cte = ChartData->GetChartTableEntry(i); ChartTypeEnum chart_type = (ChartTypeEnum)cte.GetChartType(); if(chart_type != CHART_TYPE_KAP) continue; wxString CompressedCacheFilePath = CompressedCachePath(ChartData->GetDBChartFileName(i)); wxFileName fn(CompressedCacheFilePath); // if(fn.FileExists()) /* skip if file exists */ // continue; idx_sorted_by_distance.Add(i); count++; } if(count == 0) return; wxLogMessage(wxString::Format(_T("BuildCompressedCache() count = %d"), count )); b_inCompressAllCharts = true; PurgeJobList(); ClearAllRasterTextures(); // Build another array of sorted compression targets. // We need to do this, as the chart table will not be invariant // after the compression threads start, so our index array will be invalid. ArrayOfCompressTargets ct_array; for(unsigned int j = 0; j<idx_sorted_by_distance.GetCount(); j++) { int i = idx_sorted_by_distance.Item(j); const ChartTableEntry &cte = ChartData->GetChartTableEntry(i); double distance = chart_dist(i); wxString filename(cte.GetpFullPath(), wxConvUTF8); compress_target *pct = new compress_target; pct->distance = distance; pct->chart_path = filename; ct_array.Add(pct); } // create progress dialog long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_CAN_SKIP; wxString msg0; msg0 = _T(" \n \n "); #ifdef __WXQT__ msg0 = _T("Very longgggggggggggggggggggggggggggggggggggggggggggg\ngggggggggggggggggggggggggggggggggggggggggggg top line "); #endif for(int i=0 ; i < m_max_jobs+1 ; i++) msg0 += _T("\n "); m_progDialog = new wxGenericProgressDialog(); wxFont *qFont = GetOCPNScaledFont(_("Dialog")); int fontSize = qFont->GetPointSize(); wxFont *sFont; wxSize csz = cc1->GetClientSize(); if(csz.x < 500 || csz.y < 500) sFont = FontMgr::Get().FindOrCreateFont( 10, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); else sFont = FontMgr::Get().FindOrCreateFont( fontSize, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); m_progDialog->SetFont( *sFont ); // Should we use "compact" screen layout? wxScreenDC sdc; int height, width; sdc.GetTextExtent(_T("[WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW]"), &width, &height, NULL, NULL, sFont); if(width > (csz.x / 2)) m_bcompact = true; m_progDialog->Create(_("OpenCPN Compressed Cache Update"), msg0, count+1, NULL, style ); // Make sure the dialog is big enough to be readable m_progDialog->Hide(); wxSize sz = m_progDialog->GetSize(); sz.x = csz.x * 9 / 10; m_progDialog->SetSize( sz ); m_progDialog->Layout(); wxSize sza = m_progDialog->GetSize(); wxSize pprog_size = sz; m_progDialog->Centre(); m_progDialog->Show(); m_progDialog->Raise(); m_skipout = false; m_skip = false; for( m_jcnt = 0; m_jcnt<ct_array.GetCount(); m_jcnt++) { wxString filename = ct_array.Item(m_jcnt).chart_path; wxString CompressedCacheFilePath = CompressedCachePath(filename); double distance = ct_array.Item(m_jcnt).distance; ChartBase *pchart = ChartData->OpenChartFromDBAndLock( filename, FULL_INIT ); if(!pchart) /* probably a corrupt chart */ continue; // bad things if more than one texfactory for a chart g_glTextureManager->PurgeChartTextures( pchart, true ); ChartBaseBSB *pBSBChart = dynamic_cast<ChartBaseBSB*>( pchart ); if(pBSBChart) { glTexFactory *tex_fact = new glTexFactory(pchart, g_raster_format); m_progMsg.Printf( _("Distance from Ownship: %4.0f NMi\n"), distance); m_progMsg.Prepend(_T("Preparing RNC Cache...\n")); if(m_skipout) { g_glTextureManager->PurgeJobList(); ChartData->DeleteCacheChart(pchart); delete tex_fact; break; } int size_X = pBSBChart->GetSize_X(); int size_Y = pBSBChart->GetSize_Y(); int tex_dim = g_GLOptions.m_iTextureDimension; int nx_tex = ceil( (float)size_X / tex_dim ); int ny_tex = ceil( (float)size_Y / tex_dim ); int nt = ny_tex * nx_tex; wxRect rect; rect.y = 0; rect.width = tex_dim; rect.height = tex_dim; for( int y = 0; y < ny_tex; y++ ) { rect.x = 0; for( int x = 0; x < nx_tex; x++ ) { for(int level = 0; level < g_mipmap_max_level + 1; level++ ) if(!tex_fact->IsLevelInCache( level, rect, global_color_scheme )){ goto schedule; } rect.x += rect.width; } rect.y += rect.height; } // Free all possible memory ChartData->DeleteCacheChart(pchart); delete tex_fact; continue; schedule: ScheduleJob(tex_fact, wxRect(), 0, false, true, true, false); while(!m_skip) { ::wxYield(); int cnt = GetJobCount() - GetRunningJobCount(); if(!cnt) break; wxThread::Sleep(1); } if(m_skipout) { g_glTextureManager->PurgeJobList(); ChartData->DeleteCacheChart(pchart); delete tex_fact; break; } } } while(GetRunningJobCount()) { wxThread::Sleep(1); ::wxYield(); } b_inCompressAllCharts = false; delete m_progDialog; m_progDialog = NULL; }