diff options
author | Robert C. Helling <helling@atdotde.de> | 2017-11-27 17:36:21 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2017-12-01 15:47:51 -0800 |
commit | a9703628c4c4d3b1226d4ea86b3079718940e14e (patch) | |
tree | c008eb9c45ef2b02425c086b39877d35cc34ec5f | |
parent | f159792b8050bb6d07dbf29c525dc5e86da2688b (diff) | |
download | subsurface-a9703628c4c4d3b1226d4ea86b3079718940e14e.tar.gz |
Actually compute variations in background
This reenables the computation of plan variations but now in a separate
thread. Once finieshed, a signal is sent to update the notes.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
-rw-r--r-- | core/planner.c | 4 | ||||
-rw-r--r-- | desktop-widgets/diveplanner.h | 2 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 10 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.h | 3 | ||||
-rw-r--r-- | qt-models/diveplannermodel.cpp | 89 | ||||
-rw-r--r-- | qt-models/diveplannermodel.h | 5 |
6 files changed, 71 insertions, 42 deletions
diff --git a/core/planner.c b/core/planner.c index 9c1ae2e6c..8fb03015b 100644 --- a/core/planner.c +++ b/core/planner.c @@ -688,7 +688,6 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i int decostopcounter = 0; set_gf(diveplan->gflow, diveplan->gfhigh); - lock_planner(); set_vpmb_conservatism(diveplan->vpmb_conservatism); if (!diveplan->surface_pressure) diveplan->surface_pressure = SURFACE_PRESSURE; @@ -733,7 +732,6 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i transitiontime = depth / 75; /* this still needs to be made configurable */ plan_add_segment(diveplan, transitiontime, 0, current_cylinder, po2, false); create_dive_from_plan(diveplan, dive, is_planner); - unlock_planner(); return false; } @@ -820,7 +818,6 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i free(stoplevels); free(gaschanges); - unlock_planner(); return false; } @@ -1084,7 +1081,6 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i free(stoplevels); free(gaschanges); free(bottom_cache); - unlock_planner(); return decodive; } diff --git a/desktop-widgets/diveplanner.h b/desktop-widgets/diveplanner.h index 955fc690a..8f42dd21d 100644 --- a/desktop-widgets/diveplanner.h +++ b/desktop-widgets/diveplanner.h @@ -55,7 +55,6 @@ slots: void printDecoPlan(); void setSurfacePressure(int surface_pressure); void setSalinity(int salinity); - private: Ui::DivePlanner ui; QAbstractButton *replanButton; @@ -103,6 +102,7 @@ public: explicit PlannerDetails(QWidget *parent = 0); QPushButton *printPlan() const { return ui.printPlan; } QTextEdit *divePlanOutput() const { return ui.divePlanOutput; } + QLabel *divePlannerOutputLabel() const { return ui.divePlanOutputLabel; } private: Ui::plannerDetails ui; diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index 6d4c36dc1..12592ece0 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -212,6 +212,7 @@ MainWindow::MainWindow() : QMainWindow(), connect(information(), SIGNAL(dateTimeChanged()), graphics(), SLOT(dateTimeChanged())); connect(DivePlannerPointsModel::instance(), SIGNAL(planCreated()), this, SLOT(planCreated())); connect(DivePlannerPointsModel::instance(), SIGNAL(planCanceled()), this, SLOT(planCanceled())); + connect(DivePlannerPointsModel::instance(), SIGNAL(variationsComputed(QString)), this, SLOT(updateVariations(QString))); connect(plannerDetails->printPlan(), SIGNAL(pressed()), divePlannerWidget(), SLOT(printDecoPlan())); connect(this, SIGNAL(startDiveSiteEdit()), this, SLOT(on_actionDiveSiteEdit_triggered())); connect(information(), SIGNAL(diveSiteChanged(struct dive_site *)), mapWidget, SLOT(centerOnDiveSite(struct dive_site *))); @@ -445,7 +446,6 @@ void MainWindow::enableDisableCloudActions() PlannerDetails *MainWindow::plannerDetails() const { return qobject_cast<PlannerDetails*>(applicationState["PlanDive"].bottomRight); } - PlannerSettingsWidget *MainWindow::divePlannerSettingsWidget() { return qobject_cast<PlannerSettingsWidget*>(applicationState["PlanDive"].bottomLeft); } @@ -899,6 +899,14 @@ void MainWindow::setPlanNotes() plannerDetails()->divePlanOutput()->setHtml(displayed_dive.notes); } +void MainWindow::updateVariations(QString variations) +{ + QString notes = QString(displayed_dive.notes); + free(displayed_dive.notes); + displayed_dive.notes = strdup(notes.replace("VARIATIONS", variations).toUtf8().data()); + plannerDetails()->divePlanOutput()->setHtml(displayed_dive.notes); +} + void MainWindow::printPlan() { #ifndef NO_PRINTING diff --git a/desktop-widgets/mainwindow.h b/desktop-widgets/mainwindow.h index 75c32c2e4..ca1bf8962 100644 --- a/desktop-widgets/mainwindow.h +++ b/desktop-widgets/mainwindow.h @@ -15,6 +15,7 @@ #include <QProgressDialog> #include "ui_mainwindow.h" +#include "ui_plannerDetails.h" #include "desktop-widgets/notificationwidget.h" #include "core/windowtitleupdate.h" #include "core/gpslocation.h" @@ -186,6 +187,8 @@ slots: void socialNetworkRequestUpload(); void facebookLoggedIn(); void facebookLoggedOut(); + void updateVariations(QString); + private: Ui::MainWindow ui; diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 96b5b9c0a..6413fc251 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -11,6 +11,7 @@ #include <QApplication> #include <QTextDocument> #include <QtConcurrent> +#include <desktop-widgets/mainwindow.h> #define UNIT_FACTOR ((prefs.units.length == units::METERS) ? 1000.0 / 60.0 : feet_to_mm(1.0) / 60.0) @@ -922,8 +923,14 @@ void DivePlannerPointsModel::createTemporaryPlan() if (recalcQ() && !diveplan_empty(&diveplan)) { struct decostop stoptable[60]; struct deco_state plan_deco_state; + struct diveplan *plan_copy; + plan(&plan_deco_state, &diveplan, &displayed_dive, DECOTIMESTEP, stoptable, &cache, isPlanner(), false); - //QtConcurrent::run(this, &DivePlannerPointsModel::computeVariations, &ds_after_previous_dives); + plan_copy = (struct diveplan *)malloc(sizeof(struct diveplan)); + lock_planner(); + cloneDiveplan(&diveplan, plan_copy); + unlock_planner(); + QtConcurrent::run(this, &DivePlannerPointsModel::computeVariations, plan_copy, &plan_deco_state); final_deco_state = plan_deco_state; emit calculatedPlanNotes(); } @@ -950,14 +957,13 @@ void DivePlannerPointsModel::saveDuplicatePlan() createPlan(true); } -struct divedatapoint * DivePlannerPointsModel::cloneDiveplan(struct diveplan *plan_copy) +struct divedatapoint * DivePlannerPointsModel::cloneDiveplan(struct diveplan *plan_src, struct diveplan *plan_copy) { divedatapoint *src, *last_segment; divedatapoint **dp; - lock_planner(); - src = diveplan.dp; - *plan_copy = diveplan; + src = plan_src->dp; + *plan_copy = *plan_src; dp = &plan_copy->dp; while (src && (!src->time || src->entered)) { *dp = (struct divedatapoint *)malloc(sizeof(struct divedatapoint)); @@ -970,7 +976,6 @@ struct divedatapoint * DivePlannerPointsModel::cloneDiveplan(struct diveplan *pl last_segment = plan_copy->dp; while (last_segment && last_segment->next && last_segment->next->next) last_segment = last_segment->next; - unlock_planner(); return last_segment; } @@ -1008,9 +1013,9 @@ int DivePlannerPointsModel::analyzeVariations(struct decostop *min, struct decos return (leftsum + rightsum) / 2; } -void DivePlannerPointsModel::computeVariations(struct deco_state *ds) +void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, struct deco_state *previos_ds) { - return; + bool oldRecalc = setRecalc(false); struct dive *dive = alloc_dive(); copy_dive(&displayed_dive, dive); @@ -1018,62 +1023,71 @@ void DivePlannerPointsModel::computeVariations(struct deco_state *ds) struct deco_state *cache = NULL, *save = NULL; struct diveplan plan_copy; struct divedatapoint *last_segment; + struct deco_state ds = *previos_ds; + + if(!original_plan) { + setRecalc(oldRecalc); + return; + } if(in_planner() && prefs.display_variations) { int my_instance = ++instanceCounter; - cache_deco_state(ds, &save); - cloneDiveplan(&plan_copy); + cache_deco_state(&ds, &save); + + last_segment = cloneDiveplan(original_plan, &plan_copy); + if (!last_segment) { + goto finish; + } if (my_instance != instanceCounter) - return; - plan(ds, &plan_copy, dive, 1, original, &cache, true, false); + goto finish; + plan(&ds, &plan_copy, dive, 1, original, &cache, true, false); free_dps(&plan_copy); - restore_deco_state(save, ds, false); + restore_deco_state(save, &ds, false); - last_segment = cloneDiveplan(&plan_copy); + last_segment = cloneDiveplan(original_plan, &plan_copy); last_segment->depth.mm += 1000; last_segment->next->depth.mm += 1000; if (my_instance != instanceCounter) - return; - plan(ds, &plan_copy, dive, 1, deeper, &cache, true, false); + goto finish; + plan(&ds, &plan_copy, dive, 1, deeper, &cache, true, false); free_dps(&plan_copy); - restore_deco_state(save, ds, false); + restore_deco_state(save, &ds, false); - last_segment = cloneDiveplan(&plan_copy); + last_segment = cloneDiveplan(original_plan, &plan_copy); last_segment->depth.mm -= 1000; last_segment->next->depth.mm -= 1000; if (my_instance != instanceCounter) - return; - plan(ds, &plan_copy, dive, 1, shallower, &cache, true, false); + goto finish; + plan(&ds, &plan_copy, dive, 1, shallower, &cache, true, false); free_dps(&plan_copy); - restore_deco_state(save, ds, false); + restore_deco_state(save, &ds, false); - last_segment = cloneDiveplan(&plan_copy); + last_segment = cloneDiveplan(original_plan, &plan_copy); last_segment->next->time += 60; if (my_instance != instanceCounter) - return; - plan(ds, &plan_copy, dive, 1, longer, &cache, true, false); + goto finish; + plan(&ds, &plan_copy, dive, 1, longer, &cache, true, false); free_dps(&plan_copy); - restore_deco_state(save, ds, false); + restore_deco_state(save, &ds, false); - last_segment = cloneDiveplan(&plan_copy); + last_segment = cloneDiveplan(original_plan, &plan_copy); last_segment->next->time -= 60; if (my_instance != instanceCounter) - return; - plan(ds, &plan_copy, dive, 1, shorter, &cache, true, false); + goto finish; + plan(&ds, &plan_copy, dive, 1, shorter, &cache, true, false); free_dps(&plan_copy); - restore_deco_state(save, ds, false); + restore_deco_state(save, &ds, false); +finish: + free_dps(original_plan); + free(original_plan); #ifdef SHOWSTOPVARIATIONS printf("\n\n"); #endif - QString notes(displayed_dive.notes); - free(displayed_dive.notes); - char buf[200]; sprintf(buf, "+ %d:%02d /m + %d:%02d /min", FRACTION(analyzeVariations(shallower, original, deeper, "m"),60), FRACTION(analyzeVariations(shorter, original, longer, "min"), 60)); - - displayed_dive.notes = strdup(notes.replace("VARIATIONS", QString(buf)).toUtf8().data()); + emit variationsComputed(QString(buf)); } setRecalc(oldRecalc); } @@ -1090,6 +1104,13 @@ void DivePlannerPointsModel::createPlan(bool replanCopy) //TODO: C-based function here? struct decostop stoptable[60]; plan(&ds_after_previous_dives, &diveplan, &displayed_dive, DECOTIMESTEP, stoptable, &cache, isPlanner(), true); + struct diveplan *plan_copy; + plan_copy = (struct diveplan *)malloc(sizeof(struct diveplan)); + lock_planner(); + cloneDiveplan(&diveplan, plan_copy); + unlock_planner(); + computeVariations(plan_copy, &ds_after_previous_dives); + free(cache); if (!current_dive || displayed_dive.id != current_dive->id) { // we were planning a new dive, not re-planning an existing on diff --git a/qt-models/diveplannermodel.h b/qt-models/diveplannermodel.h index 5e04c9d79..3070b36cd 100644 --- a/qt-models/diveplannermodel.h +++ b/qt-models/diveplannermodel.h @@ -110,13 +110,14 @@ signals: void startTimeChanged(QDateTime); void recreationChanged(bool); void calculatedPlanNotes(); + void variationsComputed(QString); private: explicit DivePlannerPointsModel(QObject *parent = 0); void createPlan(bool replanCopy); struct diveplan diveplan; - struct divedatapoint *cloneDiveplan(struct diveplan *plan_copy); - void computeVariations(struct deco_state *ds); + struct divedatapoint *cloneDiveplan(struct diveplan *plan_src, struct diveplan *plan_copy); + void computeVariations(struct diveplan *diveplan, struct deco_state *ds); int analyzeVariations(struct decostop *min, struct decostop *mid, struct decostop *max, const char *unit); Mode mode; bool recalc; |