From 922c945f5a5199fb27f9b68272157a238d2c371e Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Tue, 5 Apr 2016 22:54:54 -0700 Subject: QML UI: more hacking around with git progress reporting I gave up on the magic numbers and instead report simply linear progress. Signed-off-by: Dirk Hohndel --- core/checkcloudconnection.cpp | 7 ++-- core/git-access.c | 90 +++++++++++++++++++------------------------ core/git-access.h | 4 +- core/load-git.c | 4 ++ core/save-git.c | 8 ++-- mobile-widgets/qmlmanager.cpp | 24 ++++++------ 6 files changed, 66 insertions(+), 71 deletions(-) diff --git a/core/checkcloudconnection.cpp b/core/checkcloudconnection.cpp index f29d971ba..ef2e516e8 100644 --- a/core/checkcloudconnection.cpp +++ b/core/checkcloudconnection.cpp @@ -51,17 +51,18 @@ bool CheckCloudConnection::checkServer() mgr->deleteLater(); if (verbose > 1) qWarning() << "Cloud storage: successfully checked connection to cloud server"; - git_storage_update_progress(last_git_storage_update_val + 1, "successfully checked cloud connection"); + git_storage_update_progress(false, "successfully checked cloud connection"); return true; } } else if (seconds < 5) { - git_storage_update_progress(last_git_storage_update_val + 1, "waited 1 sec for cloud connection"); + QString text = QString("waited %1 sec for cloud connetion").arg(seconds); + git_storage_update_progress(false, qPrintable(text)); } else { disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit())); reply->abort(); } } - git_storage_update_progress(last_git_storage_update_val + 1, "cloud connection failed"); + git_storage_update_progress(false, "cloud connection failed"); if (verbose) qDebug() << "connection test to cloud server failed" << reply->error() << reply->errorString() << diff --git a/core/git-access.c b/core/git-access.c index 8f3b1f8d6..1547dd654 100644 --- a/core/git-access.c +++ b/core/git-access.c @@ -22,9 +22,9 @@ bool is_subsurface_cloud = false; -int (*update_progress_cb)(int, const char *) = NULL; +int (*update_progress_cb)(bool, const char *) = NULL; -void set_git_update_cb(int(*cb)(int, const char *)) +void set_git_update_cb(int(*cb)(bool, const char *)) { update_progress_cb = cb; } @@ -35,80 +35,68 @@ void set_git_update_cb(int(*cb)(int, const char *)) // proportional - some parts are based on compute performance, some on network speed) // they also provide information where in the process we are so we can analyze the log // to understand which parts of the process take how much time. - -// last_git_storage_update_val is used to detect when we suddenly go back to smaller -// "percentage" value because we are back to executing earlier code a second (or third -// time) in that case a negative percentage value is sent to the callback function as a -// special case to mark that situation. Overall this ensures monotonous percentage values -int last_git_storage_update_val; - -int git_storage_update_progress(int percent, const char *text) +int git_storage_update_progress(bool reset, const char *text) { - static int delta = 0; - - if (percent == 0) { - delta = 0; - } else if (percent > 0 && percent < last_git_storage_update_val) { - delta = last_git_storage_update_val + delta; - if (update_progress_cb) - (*update_progress_cb)(-delta, "DELTA"); - if (verbose) - fprintf(stderr, "set git storage percentage delta to %d\n", delta); - } - - last_git_storage_update_val = percent; - - percent += delta; - int ret = 0; if (update_progress_cb) - ret = (*update_progress_cb)(percent, text); + ret = (*update_progress_cb)(reset, text); return ret; } // the checkout_progress_cb doesn't allow canceling of the operation -// map the git progress to 70..90% of overall progress +// map the git progress to 20% of overall progress static void progress_cb(const char *path, size_t completed_steps, size_t total_steps, void *payload) { (void) path; (void) payload; + static size_t last_percent = -1; - int percent = 0; - if (total_steps) - percent = 70 + 20 * completed_steps / total_steps; - (void)git_storage_update_progress(percent, "checkout_progress_cb"); + if (total_steps && 20 * completed_steps / total_steps > last_percent) { + (void)git_storage_update_progress(false, "checkout_progress_cb"); + last_percent = 20 * completed_steps / total_steps; + } } // this randomly assumes that 80% of the time is spent on the objects and 20% on the deltas -// map the git progress to 70..90% of overall progress +// map the git progress to 20% of overall progress // if the user cancels the dialog this is passed back to libgit2 static int transfer_progress_cb(const git_transfer_progress *stats, void *payload) { (void) payload; + static int last_percent = -1; int percent = 0; if (stats->total_objects) - percent = 70 + 16 * stats->received_objects / stats->total_objects; + percent = 16 * stats->received_objects / stats->total_objects; if (stats->total_deltas) percent += 4 * stats->indexed_deltas / stats->total_deltas; /* for debugging this is useful char buf[100]; snprintf(buf, 100, "transfer cb rec_obj %d tot_obj %d idx_delta %d total_delta %d local obj %d", stats->received_objects, stats->total_objects, stats->indexed_deltas, stats->total_deltas, stats->local_objects); - return git_storage_update_progress(percent, buf); + return git_storage_update_progress(false, buf); */ - return git_storage_update_progress(percent, "transfer cb"); + if (percent > last_percent) { + last_percent = percent; + return git_storage_update_progress(false, "transfer cb"); + } + return 0; } -// the initial push to sync the repos is mapped to 10..15% of overall progress +// the initial push to sync the repos is mapped to 10% of overall progress static int push_transfer_progress_cb(unsigned int current, unsigned int total, size_t bytes, void *payload) { (void) bytes; (void) payload; - + static int last_percent = -1; int percent = 0; + if (total != 0) - percent = 12 + 5 * current / total; - return git_storage_update_progress(percent, "push trasfer cb"); + percent = 5 * current / total; + if (percent > last_percent) { + last_percent = percent; + return git_storage_update_progress(false, "push trasfer cb"); + } + return 0; } char *get_local_dir(const char *remote, const char *branch) @@ -419,7 +407,7 @@ static int try_to_update(git_repository *repo, git_remote *origin, git_reference if (verbose) fprintf(stderr, "git storage: try to update\n"); - git_storage_update_progress(9, "try to update"); + git_storage_update_progress(false, "try to update"); if (!git_reference_cmp(local, remote)) return 0; @@ -448,7 +436,7 @@ static int try_to_update(git_repository *repo, git_remote *origin, git_reference } /* Is the remote strictly newer? Use it */ if (git_oid_equal(&base, local_id)) { - git_storage_update_progress(10, "fast forward to remote"); + git_storage_update_progress(false, "fast forward to remote"); return reset_to_remote(repo, local, remote_id); } @@ -456,7 +444,7 @@ static int try_to_update(git_repository *repo, git_remote *origin, git_reference if (git_oid_equal(&base, remote_id)) { if (verbose) fprintf(stderr, "local is newer than remote, update remote\n"); - git_storage_update_progress(10, "git_update_remote, local was newer"); + git_storage_update_progress(false, "git_update_remote, local was newer"); return update_remote(repo, origin, local, remote, rt); } /* Merging a bare repository always needs user action */ @@ -474,7 +462,7 @@ static int try_to_update(git_repository *repo, git_remote *origin, git_reference return report_error("Local and remote do not match, local branch not HEAD - cannot update"); } /* Ok, let's try to merge these */ - git_storage_update_progress(11, "try to merge"); + git_storage_update_progress(false, "try to merge"); ret = try_to_git_merge(repo, &local, remote, &base, local_id, remote_id); if (ret == 0) return update_remote(repo, origin, local, remote, rt); @@ -496,7 +484,7 @@ static int check_remote_status(git_repository *repo, git_remote *origin, const c if (verbose) fprintf(stderr, "git storage: check remote status\n"); - git_storage_update_progress(7, "git check remote status"); + git_storage_update_progress(false, "git check remote status"); if (git_branch_lookup(&local_ref, repo, branch, GIT_BRANCH_LOCAL)) { if (is_subsurface_cloud) @@ -516,7 +504,7 @@ static int check_remote_status(git_repository *repo, git_remote *origin, const c else if (rt == RT_HTTPS) opts.callbacks.credentials = credential_https_cb; opts.callbacks.certificate_check = certificate_check_cb; - git_storage_update_progress(8, "git remote push (no remote existed)"); + git_storage_update_progress(false, "git remote push (no remote existed)"); error = git_remote_push(origin, &refspec, &opts); } else { error = try_to_update(repo, origin, local_ref, remote_ref, remote, branch, rt); @@ -540,7 +528,7 @@ int sync_with_remote(git_repository *repo, const char *remote, const char *branc } if (verbose) fprintf(stderr, "sync with remote %s[%s]\n", remote, branch); - git_storage_update_progress(2, "sync with remote"); + git_storage_update_progress(false, "sync with remote"); git_repository_config(&conf, repo); if (rt == RT_HTTPS && getProxyString(&proxy_string)) { if (verbose) @@ -567,7 +555,7 @@ int sync_with_remote(git_repository *repo, const char *remote, const char *branc if (rt == RT_HTTPS && !canReachCloudServer()) { // this is not an error, just a warning message, so return 0 report_error("Cannot connect to cloud server, working with local copy"); - git_storage_update_progress(18, "can't reach cloud server, working with local copy"); + git_storage_update_progress(false, "can't reach cloud server, working with local copy"); return 0; } if (verbose) @@ -579,7 +567,7 @@ int sync_with_remote(git_repository *repo, const char *remote, const char *branc else if (rt == RT_HTTPS) opts.callbacks.credentials = credential_https_cb; opts.callbacks.certificate_check = certificate_check_cb; - git_storage_update_progress(6, "git fetch remote"); + git_storage_update_progress(false, "git fetch remote"); error = git_remote_fetch(origin, NULL, &opts, NULL); // NOTE! A fetch error is not fatal, we just report it if (error) { @@ -594,7 +582,7 @@ int sync_with_remote(git_repository *repo, const char *remote, const char *branc error = check_remote_status(repo, origin, remote, branch, rt); } git_remote_free(origin); - git_storage_update_progress(18, "done with sync with remote"); + git_storage_update_progress(false, "done with sync with remote"); return error; } @@ -744,7 +732,7 @@ static struct git_repository *get_remote_repo(const char *localdir, const char * if (verbose > 1) { fprintf(stderr, "git_remote_repo: accessing %s\n", remote); } - git_storage_update_progress(1, "start git interaction"); + git_storage_update_progress(false, "start git interaction"); /* Do we already have a local cache? */ if (!stat(localdir, &st)) { if (!S_ISDIR(st.st_mode)) { diff --git a/core/git-access.h b/core/git-access.h index 6dbc22488..f098f1e8d 100644 --- a/core/git-access.h +++ b/core/git-access.h @@ -24,8 +24,8 @@ extern int do_git_save(git_repository *repo, const char *branch, const char *rem extern const char *saved_git_id; extern void clear_git_id(void); extern void set_git_id(const struct git_oid *); -void set_git_update_cb(int (*)(int, const char *)); -int git_storage_update_progress(int percent, const char *text); +void set_git_update_cb(int(*)(bool, const char *)); +int git_storage_update_progress(bool reset, const char *text); char *get_local_dir(const char *remote, const char *branch); extern int last_git_storage_update_val; diff --git a/core/load-git.c b/core/load-git.c index a1f2d2031..339621c63 100644 --- a/core/load-git.c +++ b/core/load-git.c @@ -1664,15 +1664,19 @@ static int do_git_load(git_repository *repo, const char *branch) git_commit *commit; git_tree *tree; + git_storage_update_progress(false, "do_git_load, find the commit"); ret = find_commit(repo, branch, &commit); if (ret) return ret; + git_storage_update_progress(false, "git commit tree"); if (git_commit_tree(&tree, commit)) return report_error("Could not look up tree of commit in branch '%s'", branch); + git_storage_update_progress(false, "load dives from tree"); ret = load_dives_from_tree(repo, tree); if (!ret) set_git_id(git_commit_id(commit)); git_object_free((git_object *)tree); + git_storage_update_progress(false, "done do_git_load"); return ret; } diff --git a/core/save-git.c b/core/save-git.c index a8120cfeb..1afb720fe 100644 --- a/core/save-git.c +++ b/core/save-git.c @@ -923,7 +923,7 @@ static int create_git_tree(git_repository *repo, struct dir *root, bool select_o struct dive *dive; dive_trip_t *trip; - git_storage_update_progress(20, "start create git tree"); + git_storage_update_progress(false, "start create git tree"); save_settings(repo, root); save_divesites(repo, root); @@ -932,7 +932,7 @@ static int create_git_tree(git_repository *repo, struct dir *root, bool select_o trip->index = 0; /* save the dives */ - git_storage_update_progress(22, "start saving dives"); + git_storage_update_progress(false, "start saving dives"); for_each_dive(i, dive) { struct tm tm; struct dir *tree; @@ -965,7 +965,7 @@ static int create_git_tree(git_repository *repo, struct dir *root, bool select_o save_one_dive(repo, tree, dive, &tm, cached_ok); } - git_storage_update_progress(25, "done creating git tree"); + git_storage_update_progress(false, "done creating git tree"); return 0; } @@ -1196,7 +1196,7 @@ int do_git_save(git_repository *repo, const char *branch, const char *remote, bo fprintf(stderr, "git storage: do git save\n"); if (!create_empty) // so we are actually saving the dives - git_storage_update_progress(19, "start git save"); + git_storage_update_progress(false, "start git save"); /* * Check if we can do the cached writes - we need to diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index 1f6b1342d..d030f5a72 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -32,29 +32,31 @@ static void appendTextToLogStandalone(const char *text) self->appendTextToLog(QString(text)); } -extern "C" int gitProgressCB(int percent, const char *text) +extern "C" int gitProgressCB(bool reset, const char *text) { static QElapsedTimer timer; - static qint64 lastTime = 0; - static int lastPercent = -100; + static qint64 lastTime; + static QString lastText; static QMLManager *self; + static int lastPercent; if (!self) self = QMLManager::instance(); - if (!timer.isValid() || percent == 0) { + if (!timer.isValid() || reset) { timer.restart(); lastTime = 0; - lastPercent = -100; + lastPercent = 0; + lastText.clear(); } if (self) { qint64 elapsed = timer.elapsed(); // don't show the same status twice in 200ms - if (percent == lastPercent && elapsed - lastTime < 200) + if (lastText == text && elapsed - lastTime < 200) return 0; - self->loadDiveProgress(percent); + self->loadDiveProgress(++lastPercent); QString logText = QString::number(elapsed / 1000.0, 'f', 1) + " / " + QString::number((elapsed - lastTime) / 1000.0, 'f', 3) + - QString(" : git %1 (%2)").arg(percent).arg(text); + QString(" : git %1 (%2)").arg(lastPercent).arg(text); self->appendTextToLog(logText); qDebug() << logText; if (elapsed - lastTime > 500) @@ -326,7 +328,7 @@ void QMLManager::retrieveUserid() } setCredentialStatus(VALID); setStartPageText("Cloud credentials valid, loading dives..."); - git_storage_update_progress(0, "load dives with valid credentials"); + git_storage_update_progress(true, "load dives with valid credentials"); loadDivesWithValidCredentials(); } @@ -740,7 +742,7 @@ void QMLManager::saveChanges() bool cbs = prefs.cloud_background_sync; if (unsaved_changes()) { appendTextToLog("Saving dives locally."); - git_storage_update_progress(0, "saving dives locally"); // reset the timers + git_storage_update_progress(true, "saving dives locally"); // reset the timers prefs.git_local_only = true; prefs.cloud_background_sync = false; if (save_dives(fileName.toUtf8().data())) { @@ -752,7 +754,7 @@ void QMLManager::saveChanges() return; } } else { - git_storage_update_progress(0, "no unsaved changes, sync with remote"); + git_storage_update_progress(true, "no unsaved changes, sync with remote"); } prefs.git_local_only = false; loadDivesWithValidCredentials(); -- cgit v1.2.3-70-g09d2